【发布时间】:2020-05-27 10:20:39
【问题描述】:
我想检测一个特定类型是否有一个成员:直接和不是继承的结果。
目的是确定特定类型是否“具有特征”,例如序列化能力。当然,为了扩展示例,即使父类型有,子类型也可能不具备序列化能力。
- 是否有(如果有)针对此请求的“标准”解决方案?
- 底部显示的不可转换指针方法是否存在缺陷(不包括其施加的限制)?
当使用is_member_function_pointer 或其他检测机制时,继承在起作用。请注意,即使 B 没有定义成员,输出也是“1”。
#include <type_traits>
#include <iostream>
struct A {
void member() { }
};
struct B : A {
};
int main()
{
std::cout << "B has member? "
<< std::is_member_function_pointer<decltype(&B::member)>::value
<< std::endl;
}
我能够实现的最接近的方法是使用不可转换的指针(B** 没有隐式转换为A**),尽管这样使用起来有点尴尬。它还强加了与类型匹配的附加参数,并防止任何直接继承。
#include <type_traits>
#include <iostream>
struct A {
// would match std::declval<B*> as B* -> A*,
// hence forcing failure through B** -> A**.
// void member(A*) { }
void member(A**) { }
};
struct B : A {
// succeeds compilation aka "found" if not commented
// void member(B**) { }
};
int main()
{
// This actually fails to compile, which is OKAY because it
// WORKS when used with SFINAE during the actual detection.
// This is just a simple example to run.
// error: invalid conversion from 'B**' to 'A**'
std::cout << "B has member? "
<< std::is_member_function_pointer<
decltype(std::declval<B>().member(std::declval<B**>()))
>::value
<< std::endl;
}
【问题讨论】:
-
您可以要求传递给函数的东西专门为您的库创建的某些类型特征,而不是尝试检测成员的存在,然后您可以检查类型特征的结果。
-
@NutCracker 不,它不会 - 除非细节被埋没。该答案/问题不涉及 inheritance,而这正是问题所在。
-
@NathanOliver 对于“不显眼的表单”也是如此:) 我希望对“显眼/内联”表单也有类似的效果。
-
@BasileStarynkevitch 所以现在我只需要为 Clang、GCC、IIC、NVCC 等编写、安装和维护插件 ;-)
标签: c++ inheritance c++14 detection typetraits