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

0xbadf00d

我正在考虑对C ++检测习惯用法提供标准库支持建议它是一种类似特征的元函数,用于确定类型是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

您可以播放现场演示现在,我想测试一个类型T是否具有带有特定签名的构造函数,例如T::T(U),另一个类型U可以使用检测惯用语来做到这一点吗?

皮特·斯科特尼克(Piotr Skotnicki)

修改detect类以允许可变参数:

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

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

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>{}, "!");

演示

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

带有继承的C ++检测习惯用法失败

我们可以使用检测惯用法来检查类是否具有带有特定签名的成员函数吗?

是否有用于下垂的python习惯用法?

Rust是否具有等同于F#typedef的习惯用法?

更好地理解命名构造函数的习惯用法

Haskell是否提供针对许多可能的数据构造函数进行模式匹配的习惯用法?

模板实例化和带有 unique_ptr 的 pimpl 习惯用法

具有非SAM接口的lambda的Java习惯用法

Java编程习惯用法:私有实现类

是否有用于在文件路径中添加斜杠的习惯用法?

是否有JavaScript习惯用法将“未定义”更改为“空”?

使用PIMPL习惯用法时,有什么方法可以限制重复样板?

使用pimpl习惯用法时如何创建私有静态const字符串

声明模板类成员和构造函数时的C ++习惯用法

具有从NameBase类到模板Name类的相关性的C ++习惯用法(或模式)

当您分支到检索到的值的表达式时,是否有类似ʻif(Value * value = getValue())`的习惯用法?

在早期检测习惯用法中使用void模板参数

为什么在使用PIMPL习惯用法时此类型不完整?

使用shared_ptr的Pimpl习惯用法处理不完整类型

使用期望函数指针的C库时的C ++习惯用法?

初始化按需持有人习惯用法

正确实施按需初始化持有人习惯用法

C ++中等效的有效Java Builder习惯用法?

按需初始化持有人习惯用法-何时加载类?

有关F#习惯用法和样式的反馈;做什么;卑鄙等

如何使用Qt的PIMPL习惯用法?

在擦除删除习惯用法中使用UnaryPredicate的否定

是否有一个习惯用法,可以为不安全的调用的结果分配一个var,以后再使用该var而不将其他所有内容嵌套在unsafe {}中?

有没有办法与其他循环条件一起使用擦除删除习惯用法?