RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 919807
Accepted
Jekyll Hyde
Jekyll Hyde
Asked:2020-12-14 12:01:40 +0000 UTC2020-12-14 12:01:40 +0000 UTC 2020-12-14 12:01:40 +0000 UTC

元函数,用于确定模板中给定类型的函子特化的存在

  • 772

元函数接受要在模板中检查的类型。如果在 Method<given_type> 上定义了括号运算符,则元函数必须返回 true。否则为假。

#include <iostream>
#include <functional>

template<typename T>
struct Method {};

template<>
struct Method<int> {
    int operator()() { return 1; }
};

template<class T>
struct is_brackets_op_defined {
  static void Check(...);

  template<typename C>
  static decltype(Method<C>::operator()) Check(const C&);

  using type = decltype(Check(
    std::declval< Method<T> >()  
  ));

  constexpr static bool value =  
    !std::is_same<void, type>();
};

int main() {
    std::cout << is_brackets_op_defined<float>::value << std::endl;
}

即使存在特化,我的实现也总是返回 false(此处为 int)

std::cout << is_brackets_op_defined<float>::value // false
std::cout << is_brackets_op_defined<int  >::value // false
c++
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    yrHeTateJlb
    2020-12-14T15:39:31Z2020-12-14T15:39:31Z

    调试元程序并不是最简单的事情,但无论如何我们都会尝试。

    is_brackets_op_defined<float>首先,让我们删除static void Check(...);. 这将帮助我们了解为什么编译器不喜欢重载版本Check(代码)。

    main.cpp:19:30: error: no matching function for call to 'is_brackets_op_defined<int>::Check(Method<int>)' main.cpp:17:42: note: candidate: 'template<class C> static decltype (Method<C>::operator()) is_brackets_op_defined<T>::Check(const C&) [with C = C; T = int]' main.cpp:17:42: note: template argument deduction/substitution failed: main.cpp: In substitution of 'template<class C> static decltype (Method<T>::operator()) is_brackets_op_defined<int>::Check<C>(const C&) [with C = Method<int>]':

    好吧,作为一个C功能Check来了Method<int>。显然,在这种情况下,构造对和Method<C>::operator()都给出了编译错误。根据 SFINAE,编译器会丢弃这个重载。intfloat

    我们需要以某种方式更改此表达式,以便它扩展为某种类型 forint并给出替换失败的 for float。在我看来&C::operator(),这将是正确的(代码)。


    原则上,这可以停止,但我不能不建议稍微简化代码。您可以将其用作返回值std::true_type,std::false_type这将丢弃std::is_same.


    UPD。评论中的问题提出了第二个改进。const C&您可以改用const C*. 这将摆脱std::declval,由于某种原因,它会在 GCC 下生成类型不完整的编译错误。

    #include <iostream>
    #include <functional>
    
    template<typename T>
    struct Method;
    
    template<>
    struct Method<int> {
        int operator()() { return 1; }
    };
    
    template<class T>
    struct is_brackets_op_defined {
      static std::false_type Check(...);
    
      template<typename C, class = decltype(&C::operator())>
      static std::true_type Check(const C*);
    
      using type = decltype(Check(static_cast<Method<T>*>(nullptr)));
    
      constexpr static bool value = type();
    };
    
    int main() {
        std::cout << std::boolalpha << is_brackets_op_defined<float>::value << std::endl;
        std::cout << std::boolalpha << is_brackets_op_defined<int>::value << std::endl;
    }
    
    • 7
  2. ixSci
    2020-12-14T15:23:31Z2020-12-14T15:23:31Z

    我不知道为什么您的代码不起作用,但是有一些东西可以使它起作用:

    template<typename C>
    static decltype(std::declval<C>().operator()()) Check(const C&);
    

    您的代码中有一个明显的问题:Method<C>::operator()不正确的 C++,因为 它是一个不做任何事情的成员函数。你需要打电话给她或获取她的地址。

    • 6
  3. user7860670
    2020-12-14T15:20:32Z2020-12-14T15:20:32Z

    它可以是这样的。请注意,辅助函数也是一个模板:

    #include <iostream>
    
    template<class T> struct
    is_brackets_op_defined
    {
        private: template<typename C> static
        char ( & Check(...) )[1];
    
        private: template<typename C> static
        char ( & Check(decltype(&C::operator ())) )[2];
    
        public: static constexpr bool value{2 == sizeof(Check<T>(nullptr))};
    };
    
    struct ClassWith
    {
        void operator ()() {}
    };
    
    struct ClassWithout
    {
    };
    
    int main()
    {
        std::cout << is_brackets_op_defined<float>::value << std::endl;
        std::cout << is_brackets_op_defined<ClassWith>::value << std::endl;
        std::cout << is_brackets_op_defined<ClassWithout>::value << std::endl;
        return 0;
    }
    

    在线编译器

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5