使用检测习惯用法确定类型是否具有带有特定签名的构造函数 [英] Using the detection idiom to determine whether a type has a constructor with a specific signature

查看:60
本文介绍了使用检测习惯用法确定类型是否具有带有特定签名的构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用建议标准库对C ++检测习惯的支持。它是一种类似特征的元函数,它确定类型 T 是否具有名为 T :: type 的类型成员。具有特定签名的成员函数,例如:

I'm playing with the proposal of standard library support for the C++ detection idiom. It is a trait-like metafunction that determines whether a type T has a type member named T::type or a member function with a specific signature, e.g.:

#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;
}

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

The code above yields the expected output

1
1
0

您可以玩实时演示。现在,我想测试 T 类型是否具有带有特定签名的构造函数,例如 T :: T(U)和另一种类型 U

You can play with a live demo. Now, I would like to test if a type T has a constructor with a specific signature, e.g. T::T(U) with another type U. Is it possible to do that using the detection idiom?

推荐答案

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

Modify the detect class to allow for variadic args:

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 { };

添加一个对无效类型进行硬编码的别名:

Add an alias that hard-codes a void type:

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>()...));

测试您的课程:

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

演示

这篇关于使用检测习惯用法确定类型是否具有带有特定签名的构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆