2017-02-27 83 views
2

我有以下代码:如何使用sfinae来检查,类型是否有operator()?

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; 
}; 

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

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

这样的代码有什么问题?

P.S:这里是简单的用法:

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; 

编辑:我使用C++ 11标准

+3

如果你需要这个实际使用,而不是教育的目的'std :: is_callable'应该适合你。 – user2176127

+0

@ user2176127,哦,谢谢,这很有趣。但我对教育目的感兴趣。而且我很抱歉,我想用C++ 11标准(我编辑过的问题) – LmTinyToon

+1

这个工作吗? (我不知道)http://stackoverflow.com/questions/257288 – javaLover

回答

4

通过正反馈的鼓舞,我会在这里发表一个简短的回答。

的问题是,你不能定义两次课,但你这样做两次: -

template <typename T> 
struct function_traits { .... some code ..... }  

C++不允许。

要检查函数是否存在,已经有a question了,可以修改它以支持operator()

这里是一个演示,在那里从Nicola Bonelli's answer非常略微修改。

#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; 
} 

我只知道几分钟前,它也适用于operator()

编辑:我改变typeofdecltype说书人LmTinyToon建议。谢谢。

2

也许使用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{}; 

如果你的编译器提供概念这可能是更简单:

template<T> 
concept bool CallableWithoutArgs= requires(T&& a){ 
    (T&&)(a)(); 
}; 
+0

我认为“概念”太棒了。它是否已经用于商业程序的开发?如果是这样,我现在就研究它。 :) – javaLover

+1

它大大提高了我的生产力,所以我实际上将它用于内部工具。它不仅改变了你的编程方式,而且改变了你的设计方式,当我在6个月前尝试时,我并没有期待它。从那以后,我一直在使用它。但是,不能用概念来编程安全关键的嵌入式系统! – Oliv

相关问题