C++ 如何使用sfinae检查类型是否有运算符()?

C++ 如何使用sfinae检查类型是否有运算符()?,c++,c++11,templates,sfinae,C++,C++11,Templates,Sfinae,我有以下代码: template <typename T> struct function_traits { typedef decltype(&T::operator()) test_type; typedef std::true_type res_type; }; template <typename T> struct function_traits { typedef std::false_type res_type; }; 模

我有以下代码:

template <typename T>
struct function_traits
{
    typedef decltype(&T::operator()) test_type;
    typedef std::true_type res_type;
};

template <typename T>
struct function_traits
{
    typedef std::false_type res_type;
};
模板
结构功能特性
{
typedef decltype(&T::operator())测试类型;
typedef std::true_type res_type;
};
模板
结构功能特性
{
typedef std::false_type res_type;
};
换句话说,我想知道类型是否有运算符()。我想我可以用SFINAE的方法来做这件事。然而,编译器告诉我们:

“function_traits”:已定义类模板

这样的代码有什么问题

注:这里有一个简单的用法:

auto f1 = [](const int a){ std::cout << a << std::endl; };
function_traits<decltype(f1)>::res_type;
auto f2 = false;
function_traits<decltype(f2)>::res_type;

auto f1=[](const int a){std::cout受到正面反馈的鼓励,我将在这里发布一个简短的答案

问题是您不能定义一个类两次,但您已经定义了两次:-

template <typename T>
struct function_traits {  .... some code ..... }    
几分钟前我才知道它也适用于
operator()


编辑:我将
typeof
更改为
decltype
作为StoryTellerLmTinyToon推荐。谢谢。

也许使用
void\t
更简单:

template <typename T,class=void>
struct callable_without_args: std::false_type{};

template <typename T>
struct callable_without_args<T
          ,std::void_t<decltype(std::declval<T>()())>>
  :std::true_type{};
模板
不带参数的结构可调用\u:std::false\u类型{};
模板
不带参数的结构可调用\u
:std::true_type{};
如果您的编译器提供以下概念,则更简单:

模板
concept bool callablewithout args=requires(T&&a){
(T&)(a);;
};

如果你需要实际使用而不是教育目的,代码> STD::ISS~可调用的< /COD>应该为你工作。@ USE2176127,哦,谢谢,很有趣。但是我对教育感兴趣。抱歉,我想用C++ 11标准(我编辑过的问题),这会起作用吗?(我不确定)@javaLover,谢谢!很有效!在你的问题中,你真的定义了两次函数特性。我认为你需要专门化。我认为“概念”太棒了。它已经用于商业程序的开发了吗?如果是的话,我现在会研究它。:)它极大地提高了我的生产力,所以我实际上将它用于内部工具。它不仅改变了你的编程方式,而且也改变了你的设计方式,我在6个月前尝试它时没有想到它。从那时起,我一直在使用它但是,这些概念将不会被用于对安全关键嵌入式系统进行编程!!
template <typename T,class=void>
struct callable_without_args: std::false_type{};

template <typename T>
struct callable_without_args<T
          ,std::void_t<decltype(std::declval<T>()())>>
  :std::true_type{};
template<T>
concept bool CallableWithoutArgs= requires(T&& a){
     (T&&)(a)();
};