使用Clang ++(v3.8.0),由于sSomeValue
是未定义的引用,以下代码无法链接。
#include <iostream>
struct MyClass
{
static constexpr int sSomeSize = 3;
static constexpr int sSomeValue = 10;
};
int foo()
{
int someArray[MyClass::sSomeSize] = {};
std::fill(std::begin(someArray), std::end(someArray), MyClass::sSomeValue);
return someArray[0];
}
int main()
{
std::cout << foo() << std::endl;
}
更确切地说:
clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
/tmp/main-c8de0c.o: In function `foo()':
main.cpp:(.text+0x2): undefined reference to `MyClass::sSomeValue'
/tmp/main-c8de0c.o: In function `main':
main.cpp:(.text+0x16): undefined reference to `MyClass::sSomeValue'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
但是,将foo
的定义更改为
int foo()
{
int someArray[MyClass::sSomeSize] = {MyClass::sSomeValue, MyClass::sSomeValue, MyClass::sSomeValue};
return someArray[0];
}
未显示相同的链接器错误,即使仍在使用sSomeValue
。
这里发生了什么?编译器是否围绕std::fill
调用进行了一些我可能不知道的优化?
请注意,g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
按照v6.3.0的预期编译,链接和输出10
。
答案 0 :(得分:1)
该错误与std :: fill无关。
如果您参考下面的文档,它会说:引用变量可以声明为constexpr(它们的初始值设定项必须是引用常量表达式):
http://en.cppreference.com/w/cpp/language/constexpr
对代码进行轻微修改可以正常工作。只需制作结构变量&#34; const&amp;&#34;如上所述。
#include <iostream>
struct MyClass
{
static constexpr int const& sSomeSize = 3;
static constexpr int const& sSomeValue = 10;
};
int foo()
{
int someArray[MyClass::sSomeSize] = {};
std::fill(std::begin(someArray), std::end(someArray), MyClass::sSomeValue);
return someArray[0];
}
int main()
{
std::cout << foo() << std::endl;
}
另请参阅此处有关constexpr
和static
的详细解释文章
&#34; Does static constexpr variable make sense?
特别是勾选答案的最后一段。