根据成员变量的类型是否存在,有条件地定义该变量

Conditionally define a member variable depending on the existence of the type it is made of

本文关键字:变量 有条件 存在 定义 是否 成员 类型      更新时间:2023-10-16

假设我有一个数据结构:

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是不完整的类型,则表达式无效。

但是,如果类型的完整性在模板实例化之间发生更改,则程序格式不正确。

现场示例