我尝试使用三个编译器(msvc2017、gcc8.2、clang7.0)编写下一个代码,msvc2017 可以正常工作,但 gcc 和 clang 不行。我想了解我的代码有什么问题,以及为什么编译器无法编译它。
#include <cassert>
#include <iostream>
#include <cstdlib>
class Downloader
{
public:
struct Hints
{
int32_t numOfMaxEasyHandles = 8;
//Hints(){} // <= if I uncomment this all works gcc+clang+msvc
//Hints() = default; // <= if I uncomment this neither clang no gcc works (msvc - works)
};
static Downloader *Create(const Hints &hints = Hints());
};
Downloader* Downloader::Create(const Hints &hints)
{
std::cout << hints.numOfMaxEasyHandles << std::endl;
return nullptr;
}
int main()
{
return 0;
}
您可以在 https://wandbox.org/ 上自己使用此代码并看到错误:
prog.cc:16:58: error: default member initializer for 'Downloader::Hints::numOfMaxEasyHandles' required before the end of its enclosing class
static Downloader *Create(const Hints &hints = Hints());
^
prog.cc:11:37: note: defined here
int32_t numOfMaxEasyHandles = 8;
^~~~
为什么即使取消注释 Hints() = default
gcc 和 clang 也不能编译此代码?
我的编译命令:
$ g++ prog.cc -std=gnu++2a
$ clang++ prog.cc -std=gnu++2a
但如果我取消对 Hints(){}
的注释,所有三个编译器都可以工作。也许这是编译器错误?提前致谢。
最佳答案
这是一个 clang 和 gcc 错误,我们有一个 clang bug report for this: default member initializer for 'm' needed within definition of enclosing class for default argument of function其中有以下示例:
#include <limits>
class A
{
public:
class B
{
public:
explicit B() = default;
~B() = default;
private:
double m = std::numeric_limits<double>::max();
};
void f(double d, const B &b = B{}) {}
};
int main()
{
A a{};
a.f(0.);
}
产生以下类似的诊断:
t.cpp(15,34): error: default member initializer for 'm' needed within definition of enclosing class 'A' outside of member functions
void f(double d, const B &b = B{}) {}
^
t.cpp(12,20): note: default member initializer declared here
double m = std::numeric_limits<double>::max();
^
Richard Smith 指出这是一个错误:
Regarding comment#0: if we want to fix this once-and-for-all, we should use the same technique we use for delayed template parsing: teach Sema to call back into the parser to parse the delayed regions on-demand. Then we would only reject the cases where there's an actual dependency cycle.
虽然没有详细解释为什么。
关于c++ - 尝试理解编译器错误信息 : default member initializer required before the end of its enclosing class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54770061/