c++ - 根据其构成的类型的存在有条件地定义一个成员变量
问题描述
假设我有一个数据结构:
struct TestData {
}
和一个带有成员变量的类:
class TestContainer {
private:
TestData data;
};
两者都是在一个用于多个测试文件的宏的 cpp 文件中定义的。
现在,如果没有定义 TestData 结构,我想在编译时删除数据成员。如果测试不需要数据,则无需定义数据成员(并且它会产生未使用的警告)。我想过使用std::enable_if
,但没有想出一个条件。另一种方法是定义一个基本模板类和专业化,如this question所示,但是如何专门化一个类型的存在?
如何才能做到这一点?
解决方案
如果您认为前向声明不存在,您可以检查结构是否存在。
此示例假定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
是不完整类型,则表达式无效。
然而,如果一个类型的完整性在模板的实例化之间发生了变化,那么程序是不正确的。
推荐阅读
- ios - SwiftUI 中的 TabView 不会改变视图
- python - Python 3.4 语法错误以及如何修复它
- python - Python:围绕圆圈放置的文本的旋转值
- sql - 将数据库 1 中的一个表更新为数据库 2 中的一个表接收转换数据错误
- flutter - 如何使用 multi_image_picker: ^4.6.7 和 Dio 上传多张图片?
- python - 将 2D 灰度重塑为 4D 以进行 Keras 模型推理
- php - SELECT count(*) from where date(week number) 等于当前周数
- javascript - Node Express 中的全局变量和类文件中的访问
- oracle - 为什么 AFTER UPDATE (FOR EACH ROW) 触发器在 (NOT DEFERRABLE) 完整性约束检查之前触发?
- python - 尝试并行运行 sklearn KMeans 的多个实例