c++ - 使用检测惯用法来确定类型是否具有带有特定签名的构造函数

标签 c++ templates c++14

我正在玩 proposal of standard library support for the C++ detection idiom 。它是一个类似特征的元函数,用于确定类型 T 是否具有名为 T::type 的类型成员或具有特定签名的成员函数,例如:

#include <iostream>


template<class...>
using void_t = void;

template<class, template<class> class, class = void_t<>>
struct detect : std::false_type { };

template<class T, template<class> class Operation>
struct detect<T, Operation, void_t<Operation<T>>> : std::true_type { };


template<class T>
using bar_t = decltype(std::declval<T>().bar());

template<class T>
using bar_int_t = decltype(std::declval<T>().bar(0));

template<class T>
using bar_string_t = decltype(std::declval<T>().bar(""));


struct foo
{
    int bar() { return 0; }
    int bar(int) { return 0; }
};


int main()
{
    std::cout << detect<foo, bar_t>{} << std::endl;
    std::cout << detect<foo, bar_int_t>{} << std::endl;
    std::cout << detect<foo, bar_string_t>{} << std::endl;

    return 0;
}

上面的代码产生了预期的输出

1
1
0

你可以玩 live demo 。现在,我想测试类型 T 是否具有具有特定签名的构造函数,例如T::T(U) 与另一种类型 U。是否可以使用检测惯用法来做到这一点?

最佳答案

修改检测类以允许可变参数:

template <typename...>
using void_t = void;

template <typename AlwaysVoid, template <typename...> class Operation, typename... Args>
struct detect_impl : std::false_type { };

template <template <typename...> class Operation, typename... Args>
struct detect_impl<void_t<Operation<Args...>>, Operation, Args...> : std::true_type { };

添加硬编码 void 类型的别名:

template <template <typename...> class Operation, typename... Args>
using detect = detect_impl<void, Operation, Args...>;
//                         ~~~^

编写检测器:

template <typename T, typename... Us>
using has_constructor = decltype(T(std::declval<Us>()...));

测试你的类(class):

static_assert(detect<has_constructor, foo, foo>{}, "!");

DEMO

关于c++ - 使用检测惯用法来确定类型是否具有带有特定签名的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35669304/

相关文章:

c++ - 如何使用 openssl 从 PKCS7.p7b 证书文件中读取证书文件?

c++ - 谷歌模拟全局模拟对象内存泄漏

wpf - 你能在数据绑定(bind)的 WPF 样式中执行 "math"吗

c - 尝试在 C 中制作模板

c++ - 模板参数包扩展语法的基本原理

C++使用lambda进行隐式构造函数调用,期望函数指针

C++ 抽象基类构造函数/析构函数 - 一般正确性

c++ - MFC CView 转入 CDockablePane

c++ - 为什么 std::cbegin 返回与 std::begin 相同的类型

c++ - 在构造函数中使用 constexpr 成员