尝试了解编译器错误消息:在其封闭类结束之前需要默认成员初始化程序 [英] Try to understand compiler error message: default member initializer required before the end of its enclosing class

查看:97
本文介绍了尝试了解编译器错误消息:在其封闭类结束之前需要默认成员初始化程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用以下三个编译器(msvc2017,gcc8.2,clang7.0)和msvc2017正常运行下一个代码,但gcc和clang无效。我想了解我的代码有什么问题,以及为什么编译器无法编译它。

I try next code with three compilers (msvc2017, gcc8.2, clang7.0) and msvc2017 works all the way, but gcc and clang not. I want to understand what is wrong with my code, and why compiler can't compile it.

#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;
                                     ^~~~

为什么gcc和clang即使未注释<$也不能编译此代码c $ c> Hints()=默认?
我的编译命令:

Why gcc and clang not compile this code even with uncomment Hints() = default? My compile commands:


  1. $ g ++ prog.cc -std = gnu ++ 2a

  2. $ clang ++ prog.cc -std = gnu ++ 2a

  1. $ g++ prog.cc -std=gnu++2a
  2. $ clang++ prog.cc -std=gnu++2a

但是,如果我取消注释 Hints(){} ,则所有这三个编译器都可以工作。也许是编译器错误?

But if I uncomment Hints(){} all three compilers works. Maybe it is compiler bug? Thanks in advance.

推荐答案

这是一个clang和gcc错误,我们有一个此错误报告:在函数的默认参数包含类的定义中需要'm'的默认成员初始化程序,具有以下示例:

This is a clang and gcc bug, we have a clang bug report for this: default member initializer for 'm' needed within definition of enclosing class for default argument of function which has the following example:

#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表示这是一个错误:

Richard Smith indicates this is a bug:


关于注释#0:如果我们要一劳永逸地解决此问题,我们应该使用与延迟模板解析相同的技术:教Sema调用返回解析器以按需解析延迟区域。那么我们只会拒绝存在实际依赖周期的情况。

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.

尽管没有详细解释原因。

Although does not explain why in details.

这篇关于尝试了解编译器错误消息:在其封闭类结束之前需要默认成员初始化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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