【问题标题】:How to test if an std::function<T> is constructible for template argument T如何测试 std::function<T> 是否可用于模板参数 T
【发布时间】:2018-08-07 03:52:34
【问题描述】:

我目前正在编写一个模板类,它采用Signature 模板参数并在内部存储一个std::function。

template <class Signature>
class Impl
{
    std::function<Signature> f;
};

这似乎工作得很好,除非Signature 模板参数无效,编译器失败并在std::function 中出现一些模板实例化错误。

现在因为Impl 客户端不需要知道Impl 的内部结构,最好向使用Impl 的开发人员输出一些人类可读的消息,说明Signature 参数无效.

使用is_invocable trait 类,类似于:

static_assert(is_invocable<Signature>::value, "Template parameter Signature is invalid");

在尝试编写这样一个 trait 类时,我想出了这个:

template <class Signature>
struct is_invocable : std::false_type
{};

template <class Signature>
struct is_invocable <std::function<Signature>> : std::true_type
{};

这似乎不起作用,因为is_invocable 不想检查Signature 是否为std::function,而是是否可以构造std::function&lt;T&gt;T 是模板参数@ 987654336@.

怎么可能写一个is_invocable 类?

注意:c++17 不可用。

【问题讨论】:

  • @StoryTeller Ahem.... std::function、lambdas、具有重载 operator() 的类和指向函数的指针等类型不计入函数类型。我想要的是更接近 std::invocable 但我不能使用 c++17
  • 令人惊讶的是,这些(和其他)正是您想要从Signature 中排除的类型。但是,如果您不费心阅读整个 wiki 页面,我就没什么好说的了。
  • @StoryTeller 确实我错了,自从我在解决解决方案之前第一次查看 std::is_function 以来我就错了,对不起。

标签: c++ c++11 templates c++14 sfinae


【解决方案1】:

正如 cmets 中建议的StoryTeller,您需要在此处使用std::is_function,因为您传递给std::function 的模板参数必须是签名

template <class Signature>
struct Impl
{
    static_assert(std::is_function<Signature>::value, "");
    std::function<Signature> f;
};

std::function 会检查它的函数对象是否可以用Signature 为你调用。

【讨论】:

  • std::function 接受 static_assert 接受的类型的 1/48。
猜你喜欢
  • 1970-01-01
  • 2017-03-23
  • 2012-05-06
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多