【问题标题】:is_function type trait for functors/function-objects仿函数/函数对象的 is_function 类型特征
【发布时间】:2016-03-10 01:13:03
【问题描述】:

考虑以下代码:

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() 如何被限定为函数类型?

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

【问题讨论】:

  • 如果您的目标是查看Bar 是否可调用(以某种方式),std::is_function 将无济于事。
  • @alfC 是的,我的第一印象是我可以查询一个类型是否是可调用的。然而,我发现这不是它的目的。

标签: c++ c++11 c++14 typetraits most-vexing-parse


【解决方案1】:

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

就是这个功能

Bar foo();

类型为Bar()

很自然,std::is_function&lt;Bar()&gt;::value 就是true

这将是相同的:

typedef Bar F();
std::cout << std::is_function<F>::value << std::endl;

【讨论】:

  • 很公平,但如果是/曾经是这样,std::is_function&lt;Bar(int, int)&gt;::value 不应该也编译成true
  • @101010:当然。 GCC 5.2 和 Clang++ 3.7 都编译它并返回 true。如果你的编译器没有,我会说这是一个编译器错误。
  • 是的,你是对的。有其他东西正在对我的代码进行网格划分。
【解决方案2】:

验证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 , "");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多