当constexpr
被引入C ++时,我开始将编译时常量编写为constexpr static
成员变量,而不是使用enum
hack。
所以我知道你不能用enum
定义的常量的地址的细微差别,在constexpr
的情况下你可以。因为你不想这样做,所以没关系。但现在我偶然发现了一些代码,我不确定你是否会不小心拿到地址。
#include <iostream>
struct A
{
constexpr static unsigned c1 = 1;
enum{ c2 = 2 };
};
template<typename T>
auto foo(T&& p)
{
return p;
}
int main()
{
std::cout << foo(A::c1) << " " << foo(A::c2) << std::endl;
return 0;
}
gcc 7
和clang 4
会很好地编译此代码,其中这些编译器的旧版本会抱怨A::c1
的未定义引用。
如果我理解正确,函数foo
将A::c1
表达式作为某种引用,因此需要获取其地址,这会导致未定义的引用。
正确的行为是什么? 标准是否要求我定义成员变量只是为了能够在完美转发的环境中使用它们?
修改
我刚注意到,如果您使用gcc 7
而不是clang 4
,-std=c++14
以及-std=c++1z
也会抱怨未定义的引用。那么标准是否有相关变化?