Using C++11, g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)。
让我们假装我有一个模板化函数(如果它不太正确,请原谅我的术语)。
我想基于应该是"字段"的编译时实例执行"通用"算法。 唯一真正改变的是我移动到 trait 类中的这些常量(这里只添加一个,但想象一下还有更多)。 最初我声明它
为constexpr field FIELD1{1};
但是在 C++11 中,非类型模板参数需要具有外部链接(不像 C++14 可以具有内部和外部链接? 因此,由于不在同一个翻译单元中,我需要使用 extern 来为其提供外部链接(对不起,如果我也破坏了该解释)。 但是通过定义它 extern,我无法使用 constexpr 来定义它,并且似乎失去该 constexpr 构造函数,此字段不再是有资格作为非类型模板参数的有效常量表达式。
有什么建议,如果有办法解决这个问题吗?对一种新的做事方法持开放态度。下面是一个简化的(不完整且非编译版本,以获取组织的要点)。
所以我看到的错误是沿着
错误:"FIELD1"的值在常量表达式中不可用
注意:"FIELD1"未声明为"constexpr" 外部常量字段字段 1; 不太确定什么是最好的选择。
我可以通过从构造函数中删除 constexpr 来摆脱第二个错误。但是我不知道如何处理常量表达式问题。
田。H
struct field
{
int thingone;
constexpr field(int i):thingone(i){}
};
extern const field FIELD1;
田。C
#include "field.H"
const field FIELD1{0};
field_traits。H
#include "field.H"
template< const field& T >
class fieldTraits;
template< >
class fieldTraits<FIELD1>
{
public:
// Let's say I have common field names
// with different constants that I want to plug
// into the "function_name" algorithm
static constexpr size_t field_val = 1;
};
功能。H
#include "field.H"
template< const field& T, typename TT = fieldTraits<T> >
void function_name()
{
// Let's pretend I'm doing something useful with that data
std::cout << T.thingone << std::endl;
std::cout << TT::field_val << std::endl;
}
不在同一个翻译单元中,我需要使用 extern 来给它外部链接(对不起,如果我也破坏了这个解释)。但是通过定义它 extern,我不能使用 constexpr 来定义它 [...]
根据我的评论,你可以。它对你不起作用,但这是一个有助于提出有效方法的步骤:
extern constexpr int i = 10;
这是完全有效的,提供了i
外部链接,并使i
可用于常量表达式。
但它不允许多个定义,因此它不能在包含在多个翻译单元中的头文件中工作。
通常,解决方法是inline
:
extern inline constexpr int i = 10;
但是变量不能在 C++11 中声明inline
。
除了。。。当它们不需要声明inline
时,因为效果已经隐式实现:
struct S {
static constexpr int i = 10;
};
现在,S::i
具有外部链接,可以在常量表达式中使用!
您甚至可能不需要为此定义自己的类,具体取决于常量的类型:考虑std::integral_constant
。你可以写
using i = std::integral_constant<int, 10>;
现在i::value
将完全按照您的要求行事。