使用空标记结构,编译器声称我缺少初始化程序,除非我没有

问题描述

好吧,我知道这类似于 Why is the compiler throwing this warning: "missing initializer"? Isn't the structure initialized?,但 GCC 肯定不会愚蠢到认为我打算初始化一些没有初始化的东西?

//main.cpp
struct IsNamed{
};

template<typename T>
struct Test{
    int foo;
};
struct Test2 : public Test<double>,public IsNamed{

};
int main(){
    Test2 x;

    Test2 y = Test2{Test<double>{}};
    return 0;
}

输出如下:

main2.cpp: In function 'int main()':
main2.cpp:18:35: warning: missing initializer for member 'Test2::<anonymous>' [-Wmissing-field-initializers]
   18 |     Test2 y = Test2{Test<double>{}};
      |                                   ^
main2.cpp:16:11: warning: unused variable 'x' [-Wunused-variable]
   16 |     Test2 x;
      |           ^
main2.cpp:18:11: warning: variable 'y' set but not used [-Wunused-but-set-variable]
   18 |     Test2 y = Test2{Test<double>{}};
      |    

唯一让我感到困惑的警告是“成员'Test2:: 缺少初始化程序”警告。这个不成立。我只需要一个可能的值,我提供它。只是为了证明确实是在继承链中包含了空类导致了这种情况,如果我删除它,这是输出

main2.cpp: In function 'int main()':
main2.cpp:16:11: warning: unused variable 'x' [-Wunused-variable]
   16 |     Test2 x;
      |           ^
main2.cpp:18:11: warning: variable 'y' set but not used [-Wunused-but-set-variable]
   18 |     Test2 y = Test2{Test<double>{}};
      |  

人们说只是忽略它,但这对我的项目不可行。我有很多的类有这个错误,它们遵循相同的标签结构模式。选择性地禁用此警告是不合理的(我也发现它在其他情况下很有用)。

如何让编译器停止抱怨?我还应该提到 Test2{Test<double>{},{}}; 不是一个合适的解决方案,因为我使用了模板代码,其中一些类没有这个问题,而有些类没有,这意味着在这些情况下这会成为一个错误

编辑:

注意这里是使用的示例 CMake,其中包括编译器选项:

cmake_minimum_required(VERSION 3.13)
project(test)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)

add_executable(test main.cpp)
target_include_directories(test
        PRIVATE
        ./
        )
target_compile_options(test PRIVATE
        $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
        -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -g -ggdb -O1>)

我也在使用 mingw64-10.2

解决方法

我只需要一个可能的值,我提供它

警告不是关于提供您“需要”的值。毕竟,编译器通常无法知道您认为需要哪些值。

警告是关于提供所有初始化程序。并且没有其他基础的初始化程序。

如何让编译器停止抱怨?

提供缺少的初始化程序:

Test2 y = Test2{Test<double>{},{}};

或者只是禁用警告。或者使用其他编译器;例如,在您的情况下,Clang 似乎没有发出警告。