根据成员变量的类型是否存在,有条件地定义该变量
Conditionally define a member variable depending on the existence of the type it is made of
假设我有一个数据结构:
struct TestData {
}
以及具有成员变量的类:
class TestContainer {
private:
TestData data;
};
两者都是在多个测试文件中使用的宏的 cpp 文件中定义的。
现在,如果没有定义 TestData 结构,我想在编译时删除数据成员。如果测试不需要数据,则无需定义数据成员(并且会生成未使用的警告(。我想过使用std::enable_if
但未能提出条件。另一种方法是定义一个基模板类和专用化,如这个问题所示,但是如何专门研究类型的存在?
如何做到这一点?
如果您认为前向声明不存在,则可以检查结构是否存在。
此示例假定始终定义或从未定义TestData
:
#include <type_traits>
// Comment this line to trigger the static assert
struct TestData {};
template<typename, typename = void>
struct MaybeData {};
template<typename T>
struct MaybeData<T, std::void_t<decltype(sizeof(T))>> {
T data;
};
struct TestContainer : MaybeData<struct TestData> {};
我们可以像这样测试我们的解决方案:
template<typename, typename = void>
constexpr auto has_data = false;
template<typename T>
constexpr auto has_data<T, std::void_t<decltype(T::data)>> = true;
static_assert(has_data<TestContainer>);
这背后的机制不是将结构本身(TestData
(作为类型发送,而是使用struct TestData
作为参数,如果存在,则引用类型,但如果不存在,则向前声明它。
然后,我们使用 sfinae 来检查sizeof(T)
是否是一个有效的表达式。如果TestData
是不完整的类型,则表达式无效。
但是,如果类型的完整性在模板实例化之间发生更改,则程序格式不正确。
现场示例
相关文章:
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 未初始化的变量有什么危险
- 如何使用 soong 命名空间来有条件地编译模块
- 有条件地将默认参数传递给函数(使用"?"运算符)
- 根据模板类型有条件地删除变量
- 有条件地选择带有 decltype() 和三元运算符的类型
- 如何使用 SFINAE 在方法调用中有条件地定义变量?
- 有条件的打印和计数在 std::map 上有限制
- 如何在 c++ 中有条件地包含标头?
- 如何仅在Qt是用ltcg构建时才有条件地启用ltcg?
- 如何在Visual Studio 2019中有条件地编译c++源文件
- C++可以有条件地向下转换类指针吗
- 根据成员变量的类型是否存在,有条件地定义该变量
- 有条件地定义了C 中的参考变量
- 等待中有条件变量的班级破坏
- 有条件的自动变量
- 我可以有条件地选择分配给哪个变量吗
- 在初始化成员变量期间有条件地处理异常
- 如何有条件地同时多线程和更新变量
- 是否可以基于宏或变量有条件地编译/运行代码