在下文中,static constexpr
成员L
在类中初始化,A
然后通过值或(通用)引用传递。后者在 Clang 中失败,但在 GCC 中失败,并且成员/非成员函数的行为略有不同。更详细地说:
#include <iostream>
using namespace std;
struct A
{
static constexpr size_t L = 4;
template <typename T>
void member_ref(T&& x) { cout << std::forward<T>(x) << endl; }
template <typename T>
void member_val(T x) { cout << x << endl; }
};
template <typename T>
void ref(T&& x) { cout << std::forward<T>(x) << endl; }
template <typename T>
void val(T x) { cout << x << endl; }
int main ()
{
A().member_ref(A::L); // Clang: linker error: undefined reference to `A::L'
A().member_val(A::L); // fine (prints 4)
ref(A::L); // Clang: compiles/links fine, no output
val(A::L); // fine (prints 4)
}
在将问题从更大的程序中分离出来的一些实验之后,我意识到我不小心使用了constexpr
变量的地址,尽管我只对值感兴趣。
我想通过(通用)引用,以便代码是通用的,并且可以在不复制的情况下使用大型结构。我认为您可以通过通用参考传递任何内容,但这里的情况似乎并非如此。我不能使用单独的(类外)定义,L
因为这是仅标头库的一部分。
因此,一种解决方法可以是在调用时生成一个值,即说size_t(A::L)
或类似的东西A::get_L()
而不是 just A::L
, where (within class A
)
static constexpr size_t get_L() { return L; }
但是这两种解决方案看起来都有些笨拙。在我的实际代码中,调用是在类中进行的,看起来call(0, L, ...)
很无辜(0, L
看起来像值)。我想让通话尽可能简单。