如何测试 std::function<T> 是否可用于模板参数 T

How to test if an std::function<T> is constructible for template argument T

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

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

这似乎工作得很好,除了当 Signature 模板参数无效时,编译器因 std::function.

中的一些模板实例化错误而失败

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

使用 is_invocable 特征 class,类似于:

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

在尝试编写这样的特征时 class,我想到了这个:

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<T> T 是模板参数 Signature.

怎么可能写成is_invocableclass?

注意:c++17 不可用。

As StoryTeller suggested in the comments, you want std::is_function 这里,因为你传递给 std::function 的模板参数必须是 signature.

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

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