gpt4 book ai didi

c++ - 为什么 Foo::inner Constexpr 不会链接,而 User Literal{Foo::inner Constexpr} 会链接?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:38:24 26 4
gpt4 key购买 nike

考虑以下简单类,这些类是我根据在实际项目中遇到的问题设计的。 Triple 是一种与内部一起使用的快速样板类型 constexpr Foo 类中的 s:

#include <iostream>

class Triple {
public:
friend
std::ostream & operator <<(std::ostream & o, Triple const & t);

constexpr Triple() : a_(0), b_(0), c_(0) { }
constexpr Triple(Triple const & other) = default;
constexpr Triple(double a, double b, double c)
: a_(a), b_(b), c_(c)
{ }

~Triple() = default;

private:
double a_, b_, c_;
};

std::ostream & operator <<(std::ostream & o, Triple const & t) {
o << "(" << t.a_ << ", " << t.b_ << ", " << t.c_ << ")";
return o;
}

class Foo {
public:
Foo() : triple_(defaultTriple) { }

Triple const & triple() const { return triple_; }
Triple & triple() { return triple_; }

constexpr static float defaultPOD{10};
constexpr static Triple defaultTriple{11.0, 22.0, 33.0};

private:
Triple triple_;
};

如果我再写一个 main()使用公共(public)内部函数 constexpr来自 Foo ,如下,会链接失败(使用g++4.7.0,在Windows 7上通过mingw-x86-64):

int main(int argc, char ** argv) {
using std::cout;
using std::endl;

cout << Foo::defaultPOD << endl;
cout << Foo::defaultTriple << endl;
}
    $ g++ -o test -O3 --std=c++11 test.cpp    e:\temp\ccwJqI4p.o:test.cpp:(.text.startup+0x28): undefined reference to `Foo::defaultTriple' collect2.exe: error: ld returned 1 exit status

However, if I write

cout << Triple{Foo::defaultTriple} << endl

而不是简单地

cout << Foo::defaultTriple << endl

它将链接并正常运行。我可以看到前者更明确地表达了编译时文字的意图,但令我惊讶的是后者不能正常工作。这是编译器错误,还是有基于 constexpr 规则的原因?只有第一个示例应该有效吗?

我会尝试其他编译器以获得更多见解,但目前 GCC 4.7.0 是我可以访问的唯一支持 constexpr 的编译器。 .

另请注意 pod 的表达式 constexpr没有明确的文字包装器也能正常工作,例如cout << Foo::defaultPOD从来没有给我带来麻烦。

最佳答案

出现在不需要常量表达式的上下文中的常量表达式可能会在程序翻译期间被评估,但它不是必需的,所以它可能是在运行时评估。

如果 constexpr static成员在程序翻译期间被评估,编译器可以使用它的初始化器来确定它的值,而不需要成员的定义。

如果成员在运行时评估的上下文中使用,则需要其定义。

cout << Foo::defaultTriple << endl您的编译器正在生成代码以执行 Foo::defaultTriple 的左值到右值转换在运行时,因此对象需要一个定义。

cout << Triple{Foo::defaultTriple} << endl编译器正在评估 Foo::defaultTriple在程序翻译期间创建临时 Triple它本身可能在运行时被评估。

除非您的 constexpr对象仅在需要常量表达式的上下文中计算,您必须为它们提供定义。

关于c++ - 为什么 Foo::inner Constexpr 不会链接,而 User Literal{Foo::inner Constexpr} 会链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10988891/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com