类静态 constexpr 的 C++ 链接器错误 [英] C++ Linker Error With Class static constexpr

查看:38
本文介绍了类静态 constexpr 的 C++ 链接器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 g++-4.6.1 --std=c++0x 编译以下简单程序:

I am compiling the following simple program with g++-4.6.1 --std=c++0x:

#include <algorithm>

struct S
{
    static constexpr int X = 10;
};

int main()
{
    return std::min(S::X, 0);
};

我收到以下链接器错误:

I get the following linker error:

/tmp/ccBj7UBt.o: In function `main':
scratch.cpp:(.text+0x17): undefined reference to `S::X'
collect2: ld returned 1 exit status

我意识到内联定义的静态成员没有定义符号,但我的(可能有缺陷的)印象是使用 constexpr 告诉编译器始终将符号视为表达式;因此,编译器会知道传递对符号 S::X 的引用是不合法的(出于同样的原因,您不能引用文字 10).

I realize that inline-defined static members do not have symbols defined, but I was under the (probably flawed) impression that using constexpr told the compiler to always treat the symbol as an expression; so, the compiler would know that it is not legal to pass a reference to the symbol S::X (for the same reason you can't take a reference to the literal 10).

但是,如果 S 被声明为命名空间,即命名空间 S"而不是结构 S",则一切都可以正常链接.

However if S is declared as namespace, i.e. "namespace S" instead of "struct S", everything links fine.

这是一个 g++ 错误还是我仍然需要使用技巧来解决这个烦恼?

Is this a g++ bug or do I still have to use a trick to workaround this annoyance?

推荐答案

我不认为这是一个错误.如果将 constexpr 更改为 const,它仍然会失败,并出现完全相同的错误.

I don't think this is a bug. If you change the constexpr to const, it still fails, with the exact same error.

您已经声明了 S::X,但没有在任何地方定义它,因此没有存储空间.如果你对它做任何需要知道它的地址的事情,那么你也需要在某个地方定义它.

You've declared S::X, but not defined it anywhere, so there's no storage for it. If you do anything with it that needs to know the address of it then you'll need to define it somewhere also.

例子:

int main() {
      int i = S::X; // fine
      foo<S::X>(); // fine
      const int *p = &S::X; // needs definition
      return std::min(S::X, 0); // needs it also
}

这样做的原因是 constexpr 可以在编译时进行评估,但不是要求这样评估,并且可以同样发生在运行时.它没有指示编译器始终将符号视为表达式",它暗示如果编译器愿意,这样做是明智和允许的.

The reason for this is that constexpr can be evaluated at compile time, but it's not required to be evaluated as such, and can equally happen at runtime. It doesn't instruct "the compiler to always treat the symbol as an expression", it hints that it would be sensible and permissible to do so if the compiler felt like it.

这篇关于类静态 constexpr 的 C++ 链接器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆