C++ 在c+;中定义未命名结构时出错+;

C++ 在c+;中定义未命名结构时出错+;,c++,struct,typedef,using,anonymous,C++,Struct,Typedef,Using,Anonymous,我的代码有问题,甚至我的教授也不知道为什么会这样 他想让我用Persontype=struct{}定义结构而不是结构的正常定义。我不明白为什么或者有什么区别 他也不希望我们在main中包含.cpp文件 结构的常规定义可以正常工作,但不适用于此 错误 In file included from ...\LABOR1TEST\main.cpp:3: ...\LABOR1TEST\test.hpp:12:6: warning: 'void test(const std::vector<<u

我的代码有问题,甚至我的教授也不知道为什么会这样

他想让我用Persontype=struct{}定义结构而不是结构的正常定义。我不明白为什么或者有什么区别

他也不希望我们在main中包含.cpp文件

结构的常规定义可以正常工作,但不适用于此

错误

In file included from ...\LABOR1TEST\main.cpp:3:
...\LABOR1TEST\test.hpp:12:6: warning: 'void test(const std::vector<<unnamed struct> >&)' used but never defined
 void test(std::vector<PersonType> const &_Personen);
      ^~~~
[100%] Linking CXX executable LABOR1TEST.exe
CMakeFiles\LABOR1TEST.dir/objects.a(main.cpp.obj): In function `main':
.../LABOR1TEST/main.cpp:12: undefined reference to `test(std::vector<._56, std::allocator<._56> > const&)'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [CMakeFiles\LABOR1TEST.dir\build.make:120: LABOR1TEST.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:95: CMakeFiles/LABOR1TEST.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:102: CMakeFiles/LABOR1TEST.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:137: LABOR1TEST] Error 2
我的解释
使用PersonType=struct{….}将在每个翻译单元中生成不同的匿名类型(
.cpp
文件,为简单起见),然后在每个翻译单元中为其命名为
PersonType
。此语句发生在
测试内部并不重要。hpp
,所有
#include
都由预处理器处理,在处理类型时也不重要

因此,两个翻译单元(
main.cpp
test.cpp
)中的
PersonType
实际上指的是不同的类型。实际上,
main.cpp
希望通过一个
PersonType
找到
test(vector const&)
,而
test.cpp
仅通过另一个
PersonType
提供
test(vector const&)
,因此链接错误

这是一个GCC错误吗? 如果去掉模板并尝试同时编译以下两个翻译单元,则可以更好地看到错误:

使用Foo=struct{};
孔隙试验(Foo);
int main(){
福福;
试验(f);
}
使用Foo=struct{};
无效测试(Foo){
}
我的GCC告诉我以下内容:

a.cpp:2:6: error: 'void test(Foo)', declared using unnamed type, is used but never defined [-fpermissive]
    2 | void test(Foo);
      |      ^~~~
a.cpp:1:7: note: 'using Foo = struct<unnamed>' does not refer to the unqualified type, so it is not used for linkage
    1 | using Foo = struct {};
      |       ^~~
a.cpp:2:6: warning: 'void test(Foo)' used but never defined
    2 | void test(Foo);
      |      ^~~~
a.cpp:2:6:错误:“void test(Foo)”,使用未命名类型声明,但从未定义[-fpermissive]
2 |孔隙试验(Foo);
|      ^~~~
a、 cpp:1:7:注意:“using Foo=struct”并不指非限定类型,因此它不用于链接
1 |使用Foo=struct{};
|       ^~~
a、 cpp:2:6:警告:已使用但从未定义“无效测试(Foo)”
2 |孔隙试验(Foo);
|      ^~~~
但是,使用Foo=struct{}替换
带有
typedef结构{}Foo显然有效,并且可以从我的GCC切换到我的Clang

评论中的M.M建议
typedef
应该可以工作,因为

在typedef声明中定义的命名类([class.pre])或未命名类,其中该类具有用于链接的typedef名称([dcl.typedef])

GCC对它的解释可能过于字面(?)而无法排除
using
,尽管它说
using
引入的名称应具有与
typedef
相同的语义

令人惊讶的是

关于你的问题 他希望我使用Persontype=struct{}来定义结构;而不是一个正常的结构定义


如果上面的文字是真的,这是一个相当奇怪的要求。这样就不可能根据
PersonType
链接不同的翻译单元。我想知道背后的原因是什么,也许你不应该在一个翻译单元之外公开
PersonType
?考虑咨询你的助教或教授。

你需要链接<代码>测试。CPP < /代码>。请出示证件。txt@yeputons好的,它在C++17[basic.link]/4.3中表示,在typedef声明中定义的未命名类的行为用于链接目的,就好像该类具有typedef名称一样。因此,也许g++是从字面上理解这一点,只是将该段落应用于
typedef
,而不是
使用
?我怀疑这是语言的意图,可能文本是在
使用之前编写的,甚至在语言中添加了
,从未被使用过revisited@yeputons[dcl.typedef]/2明确表示“这样的typedef名称具有与typedef说明符引入的名称相同的语义。”因此我倾向于将其称为g++错误,虽然从技术上讲,该标准存在缺陷,因为它给出了相互矛盾的requirements@MommeSherif祝贺您发现了标准中的一个缺陷和一个可能的g++错误。不是每个人都可以说他们已经做到了:)@M.M看看我发现了什么:事实上,经过一点研究,我对我的解释不是很确定:g++和clang++对我产生了不同的结果,并且在使用PersonType=struct{…}
typedef struct{…}PersonType
之间进行了更改。我需要进一步的研究。我用VisualStudioC++编译器在CGOLE(CHILY)的工具链中尝试过,它工作正常。而且在Linux中,g++或gcc编译器都无法工作汉克人!你是个英雄,我明天会给他看,然后再问他。真的非常感谢!!!!
#include <iostream>
#include <vector>
#include <string>
#include "test.hpp"
void test(std::vector<PersonType> const &_Personen)
{
    for (auto const  &i : _Personen)
    {
    std::cout << i.Name << std::endl;
    }
}
#include <vector>
#include <string>
#ifndef LABOR1TEST_TEST_HPP
#define LABOR1TEST_TEST_HPP

using PersonType = struct {
    std::string Name;
};
void test(std::vector<PersonType> const &_Personen);
#endif //LABOR1TEST_TEST_HPP
cmake_minimum_required(VERSION 3.17)
project(LABOR1TEST)

set(CMAKE_C++_STANDARD 11)

add_executable(LABOR1TEST main.cpp test.cpp test.hpp)
a.cpp:2:6: error: 'void test(Foo)', declared using unnamed type, is used but never defined [-fpermissive]
    2 | void test(Foo);
      |      ^~~~
a.cpp:1:7: note: 'using Foo = struct<unnamed>' does not refer to the unqualified type, so it is not used for linkage
    1 | using Foo = struct {};
      |       ^~~
a.cpp:2:6: warning: 'void test(Foo)' used but never defined
    2 | void test(Foo);
      |      ^~~~