gpt4 book ai didi

c++ - c++11 中的 constexpr 模板元信息变量

转载 作者:行者123 更新时间:2023-12-01 14:25:09 25 4
gpt4 key购买 nike

我正在尝试以结构化方式(即使用类)表示一些元信息。它只是 header ,我需要支持 c++11,所以不能使用内联变量。我想出了几个可能的解决方案,但每个都有其缺点。任何建议将不胜感激,尽管仅指出如何制作“替代 B”进行编译对我来说是一个很好的解决方案。

SthInfo::fieldA用作模板化 Processor<Type>::work(field) 的参数其中:

  • 检查“容器类型”是否与该处理器匹配
  • 并将 ID 与其他不相关的参数一起使用来做一些内部逻辑

备选方案 A - 有效但模板化的 ID

#include <type_traits>

template <typename Container, int ID>
class FieldInfo {
public:
static constexpr int id = ID;
};

template <typename T>
class Processor {
public:
template <typename Container, int ID>
void work(FieldInfo<Container, ID> field) {
static_assert(std::is_same<Container, T>::value, "Given field can't be processed - container type mismatch");
// some business logic using the ID, i.e. accessing `field.id`
int id = field.id;
}
};

struct Sth {/* contains fieldA and fieldB - just as an example */};

// SthInfo holds meta-information about fields in Sth
struct SthInfo {
static constexpr FieldInfo<Sth, 1> fieldA{};
};

int main() {
Processor<Sth> processor;
processor.work(SthInfo::fieldA);
}

这在 Linux 和 Windows 上运行良好(编译和链接)。但是,有没有办法避免 ID模板中的常量并将其作为 FieldInfo 中的字段类(class)?还有其他改进想法吗?

备选方案 B - 损坏 - 无法链接

我已尝试更改为以下代码,但它在 Linux 上没有链接(但在 Windows 上...)与 undefined reference to SthInfo::fieldA :

#include <type_traits>

template <typename Container>
class FieldInfo {
public:
const int id;
};

template <typename T>
class Processor {
public:
template <typename Container>
void work(FieldInfo<Container> field) {
static_assert(std::is_same<Container, T>::value, "Given field can't be processed - container type mismatch");
// some business logic using the ID, i.e. accessing `field.id`
int id = field.id;
}
};

struct Sth {/* contains fieldA and fieldB - just as an example */};

// SthInfo holds meta-information about fields in Sth
struct SthInfo {
static constexpr FieldInfo<Sth> fieldA{1};
};

int main() {
Processor<Sth> processor;
processor.work(SthInfo::fieldA);
}

替代 C - constexpr 函数 - 不太好用。

改变 SthInfo::fieldA到 constexpr 函数有帮助,但你必须使用 ()在应用程序代码中使用时...

#include <type_traits>

template <typename Container>
class FieldInfo {
public:
const int id;
};

template <typename T>
class Processor {
public:
template <typename Container>
void work(FieldInfo<Container> field) {
static_assert(std::is_same<Container, T>::value, "Given field can't be processed - container type mismatch");
// some business logic using the ID, i.e. accessing `field.id`
int id = field.id;
}
};

struct Sth {/* contains fieldA and fieldB - just as an example */};

// SthInfo holds meta-information about fields in Sth
struct SthInfo {
static constexpr FieldInfo<Sth> fieldA() { return FieldInfo<Sth>{1}; }
};

int main() {
Processor<Sth> processor;
processor.work(SthInfo::fieldA());
}

最佳答案

在 C++17 之前,它引入了内联变量——并使 constexpr 静态成员变量隐式内联——如果这些变量被 ODR 使用,你必须在类外定义:

const FieldInfo<Sth> SthInfo::fieldA;

请注意,这是一个非模板化变量,因此必须在一个 源文件中定义。 templated 变量的类似定义可以出现在 header 中(使用与内联变量相同的编译器/链接器支持),因此您需要使用类似

template<class T>
struct Info {
static constexpr FieldInfo<T> fieldA{1};
};
template<class T> const FieldInfo<T> Info<T>::fieldA;

关于c++ - c++11 中的 constexpr 模板元信息变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62718214/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com