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

LmT*_*oon 2 c++ templates sfinae c++11

我有以下代码:

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;
};
Run Code Online (Sandbox Code Playgroud)

换句话说,我想知道类型是否具有运算符()。我以为可以使用SFINAE的方式来做到这一点。但是编译器告诉:

'function_traits':类模板已经定义。

这样的代码怎么了?

PS:这是简单的用法:

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;
Run Code Online (Sandbox Code Playgroud)

编辑:我正在使用c ++ 11标准

jav*_*ver 5

受到积极反馈的鼓励,我将在此处发布简短答复。

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

template <typename T>
struct function_traits {  .... some code ..... }    
Run Code Online (Sandbox Code Playgroud)

C ++不允许这样做。

要检查功能是否存在,已经存在一个问题,可以对其进行修改以支持operator()

这是一个演示,与Nicola Bonelli的回答略有修改。

#include <iostream>

struct Hello
{
    void operator()() {  }
};

struct Generic {};    

// SFINAE test
template <typename T>
class has_parenthesis
{
    typedef char one;
    typedef long two;

    template <typename C> static one test( decltype(&C::operator()) ) ;
    template <typename C> static two test(...);    

public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
};

int main(int argc, char *argv[])
{
    std::cout << has_parenthesis<Hello>::value << std::endl;    //print 1
    std::cout << has_parenthesis<Generic>::value << std::endl;  //print 0
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

几分钟前我才知道它也适用operator()

编辑:我改变了typeofdecltype作为故事讲述者LmTinyToon建议。谢谢。