我试图以结构化的方式(即使用类)表示一些元信息。它只是标题,我需要支持 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
类中的字段?还有其他改进的想法吗?
备选方案 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());
}