有什么方法可以检查模板 class 在 C++14 中是否有嵌套的 class 定义(或类型定义)?
Is there any way to check if a template class has a nested class definition (or a typedef) in C++14?
我定义了以下结构:
struct NoRelationship {};
struct OneToMany {};
struct Interdependent {};
template <typename RelationType>
struct SignatureGenerator
{
using type = std::function<void()>;
};
template <>
struct SignatureGenerator<Interdependent>
{
using type = std::function<void()>;
using extra_type = std::function<void()>;
};
我需要执行 SFINAE 检查,以确定 class 是否具有“extra_type”定义。我检查了 this and this 个主题,但仍然找不到可行的解决方案。我尝试了后一个主题中的以下代码:
template <typename T>
class has_extra_type
{
typedef char yes;
struct no {char x[2];};
template<typename C> static yes test(decltype(&C::extra_type));
template<typename C> static no test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof (char)};
};
但这不起作用,因为“依赖类型名称之前缺少 'typename'”错误。如果我注释掉一般规范,编译器会告诉我:
// template<typename C> static no test(...);
错误:没有匹配函数来调用 'test'
enum { value = sizeof(test(0)) == sizeof (char)};
注意:候选模板被忽略:替换失败 [with C = SignatureGenerator]:依赖类型名称 'SignatureGenerator::extra_type' 之前缺少 'typename'
模板静态是测试(decltype(&C::extra_type));
关于如何绕过这个的任何想法?
*更新:这是我使用支票的方式:
int main() {
std::cout << has_extra_type<SignatureGenerator<OneToMany>>::value <<std::endl;
std::cout << has_extra_type<SignatureGenerator<Interdependent>>::value <<std::endl;
return 0;
}
它为两个 classes 给出 0,而我希望在第二种情况下检测到 'extra_type'。
对于 yes
重载,您正在使用:
template<typename C> static yes test(decltype(&C::extra_type)); // incorrect for types
但是,decltype
和 &
是必需的,因为您正在查看的示例正在检查是否存在 成员函数 。但是 extra_type
是一种类型,所以你不能获取它的地址,所以该表达式总是格式错误的,并且永远不会选择重载。
由于您要检查 成员类型别名 是否存在,您可以简单地执行以下操作:
template<typename C> static yes test(typename C::extra_type*);
这里是 demo。
我定义了以下结构:
struct NoRelationship {};
struct OneToMany {};
struct Interdependent {};
template <typename RelationType>
struct SignatureGenerator
{
using type = std::function<void()>;
};
template <>
struct SignatureGenerator<Interdependent>
{
using type = std::function<void()>;
using extra_type = std::function<void()>;
};
我需要执行 SFINAE 检查,以确定 class 是否具有“extra_type”定义。我检查了 this and this 个主题,但仍然找不到可行的解决方案。我尝试了后一个主题中的以下代码:
template <typename T>
class has_extra_type
{
typedef char yes;
struct no {char x[2];};
template<typename C> static yes test(decltype(&C::extra_type));
template<typename C> static no test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof (char)};
};
但这不起作用,因为“依赖类型名称之前缺少 'typename'”错误。如果我注释掉一般规范,编译器会告诉我:
// template<typename C> static no test(...);
错误:没有匹配函数来调用 'test' enum { value = sizeof(test(0)) == sizeof (char)};
注意:候选模板被忽略:替换失败 [with C = SignatureGenerator]:依赖类型名称 'SignatureGenerator::extra_type' 之前缺少 'typename' 模板静态是测试(decltype(&C::extra_type));
关于如何绕过这个的任何想法?
*更新:这是我使用支票的方式:
int main() {
std::cout << has_extra_type<SignatureGenerator<OneToMany>>::value <<std::endl;
std::cout << has_extra_type<SignatureGenerator<Interdependent>>::value <<std::endl;
return 0;
}
它为两个 classes 给出 0,而我希望在第二种情况下检测到 'extra_type'。
对于 yes
重载,您正在使用:
template<typename C> static yes test(decltype(&C::extra_type)); // incorrect for types
但是,decltype
和 &
是必需的,因为您正在查看的示例正在检查是否存在 成员函数 。但是 extra_type
是一种类型,所以你不能获取它的地址,所以该表达式总是格式错误的,并且永远不会选择重载。
由于您要检查 成员类型别名 是否存在,您可以简单地执行以下操作:
template<typename C> static yes test(typename C::extra_type*);
这里是 demo。