Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 检查类是否从模板的任何模板实例化继承_C++_Templates_Inheritance_C++11_Sfinae - Fatal编程技术网

C++ 检查类是否从模板的任何模板实例化继承

C++ 检查类是否从模板的任何模板实例化继承,c++,templates,inheritance,c++11,sfinae,C++,Templates,Inheritance,C++11,Sfinae,我编写了一个小实用程序,用于测试类型是否继承了特定模板类的某些模板实例化,可以是直接继承,也可以是通过继承继承该模板的类。这是通过使用接受所提供模板的任何模板实例化的模板函数进行SFINAE检查和默认情况下的回退重载来完成的 #包括 #包括 模板 结构派生自 { 静态constexpr bool value=decltype(isDerivedFrom::test(U())::value; 私人: 模板 静态标准::真实型试验(T); 静态标准:假_型试验(…); }; 模板 结构基{}; 结构

我编写了一个小实用程序,用于测试类型是否继承了特定模板类的某些模板实例化,可以是直接继承,也可以是通过继承继承该模板的类。这是通过使用接受所提供模板的任何模板实例化的模板函数进行SFINAE检查和默认情况下的回退重载来完成的

#包括
#包括
模板
结构派生自
{
静态constexpr bool value=decltype(isDerivedFrom::test(U())::value;
私人:
模板
静态标准::真实型试验(T);
静态标准:假_型试验(…);
};
模板
结构基{};
结构Base_D1:Base{};
结构Base_D2:Base{};
结构Base_D1_D1:Base_D1{};
结构NotDerived{};
int main()
{
std::cout您可以使用:

模板
结构派生自
{
私人:
模板
静态decltype(static_cast(std::declval()),std::true_type{})
测试(常数T&);
静态标准:假_型试验(…);
公众:
静态constexpr bool value=decltype(isDerivedFrom::test(std::declval())::value;
};

由于私有继承不可见,在最后一种情况下,trait返回
false
(对于
struct-Derived:private-Base{};
).

废弃的TR2中曾经有一个trait
std::base
std::direct\U base
部分,它仍然随GCC一起提供。您可以使用它来检查是否有任何基是模板实例化。此代码不正确,因为if
U
继承自
T
T
其中
X
!=<代码>Y
,它不会检测到继承。顺便说一句:您可以使用
静态断言(isDerivedFrom::value,“意外值”)进行编译时检查
而不是用stream进行手动目视检查。@Jarod42当然,这就是为什么我首先编写代码,打印到控制台只是感觉测试更自然。@johanneschaub多重继承的情况没有发生在我身上,很好。你建议什么解决方案?你能解释一下什么是
decltype(static_cast(std::declval())),std::true_type{})有什么作用?为什么需要静态强制转换?静态强制转换是尝试(公开)将
U
转换为
T
,并使用SFINAE删除无效的大小写。(您的代码不使用SFINAE,只使用更好的匹配).
运算符T
可以愚弄这一点吗?@Yakk不,因为转换函数从未被调用以转换为基类类型。如果
T
不是基类类型,则在尝试转换之前模板参数推导将失败。但是,我相信如果
T
具有公共构造函数
T(const U&)
。您可能希望将静态\U cast更改为
static\U cast
,这将消除此漏洞。
template<template<class> class T, class U>
struct isDerivedFrom
{
private:
    template<class V>
    static decltype(static_cast<const T<V>&>(std::declval<U>()), std::true_type{})
    test(const T<V>&);

    static std::false_type test(...);
public:
    static constexpr bool value = decltype(isDerivedFrom::test(std::declval<U>()))::value;
};