4

考虑以下代码:

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

int main() {
  std::cout << std::boolalpha << std::is_function<Bar>::value << 
}

输出是false

这并不奇怪,因为仿函数Bar不符合函数类型§8.3.5 Functions [dcl.fct]的条件。

现在考虑以下代码:

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

int main() {
  std::cout << std::boolalpha << std::is_function<Bar()>::value << std::endl;
                                                     ^^
}

注意后面的括号Bar。输出是true

如何Bar()限定为函数类型?

我的猜测是这是最令人烦恼的解析的情况,但是既然它在模板参数列表中,怎么可能呢?

4

2 回答 2

4

好吧,我不认为它是 MVP,它只是返回Bar且不带任何参数的函数的类型。

就是这个功能

Bar foo();

有类型Bar()

所以自然std::is_function<Bar()>::valuetrue

这将是相同的:

typedef Bar F();
std::cout << std::is_function<F>::value << std::endl;
于 2015-12-05T00:18:35.927 回答
1

验证它Bar是可调用的std::is_function并没有帮助。为此,您需要做其他事情。基于通用代码(取自https://stackoverflow.com/a/18603716/225186):

template<class F, class... T, typename = decltype(std::declval<F>()(std::declval<T>()...))> 
std::true_type  supports_test(const F&, const T&...);
std::false_type supports_test(...);

template<class> struct supports;
template<class F, class... T> struct supports<F(T...)> 
: decltype(supports_test(std::declval<F>(), std::declval<T>()...)){};

你可以做

struct Bar { 
  void operator()() {}
  void operator()(double) {}
};

int main(){
    static_assert( supports<Bar()>::value == true , "");
    static_assert( supports<Bar(double)>::value == true , ""); // because of overload
    static_assert( supports<Bar(int)>::value == true , ""); // because of conversion
    static_assert( supports<Bar(std::string)>::value == false , "");
}
于 2015-12-06T03:46:52.900 回答