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



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

他希望我用using Persontype= struct{};而不是结构的正常定义来定义结构。我不明白为什么或有什么区别。

他也不希望我们将.cpp文件包含在 Main 中。

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

错误

In file included from ...LABOR1TESTmain.cpp:3:
...LABOR1TESTtest.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
CMakeFilesLABOR1TEST.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]: *** [CMakeFilesLABOR1TEST.dirbuild.make:120: LABOR1TEST.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFilesMakefile2:95: CMakeFiles/LABOR1TEST.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFilesMakefile2:102: CMakeFiles/LABOR1TEST.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:137: LABOR1TEST] Error 2

这是我的代码

主.cpp

#include <iostream>
#include <vector>
#include "test.hpp"
int main() {
PersonType p;
p.Name = "Max";
std::vector<PersonType> TEMPVEC;
TEMPVEC.push_back(p);
TEMPVEC.push_back(p);
test (TEMPVEC);
return 0;
}

测试.cpp

#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;
}
}

和我的测试.hpp

#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

CMakeList.txt

cmake_minimum_required(VERSION 3.17)
project(LABOR1TEST)
set(CMAKE_C++_STANDARD 11)
add_executable(LABOR1TEST main.cpp test.cpp test.hpp)

我的解释

顶层using PersonType = struct { ..... };将在每个翻译单元(为简单起见,.cpp文件)中生成不同的匿名类型,然后在每个翻译单元中为其指定PersonType名称。这个语句发生在test.hpp中并不重要,所有#include都由预处理器处理,在处理类型时无关紧要。

因此,PersonType在两个翻译单元(main.cpptest.cpp)中实际上指的是不同的类型。实际上,main.cpp期望用一个PersonType找到test(vector<PersonType> const &),而test.cpp只为test(vector<PersonType> const&)提供另一个PersonType,因此链接错误。

这是海湾合作委员会的错误吗?

如果您摆脱模板并尝试将以下两个翻译单元编译在一起,则可以更好地看到错误:

using Foo = struct {};
void test(Foo);
int main() {
Foo f;
test(f);
}
using Foo = struct {};
void test(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);
|      ^~~~

但是,用typedef struct {} Foo;替换using Foo = struct {};显然有效,以及从我的 GCC 切换到我的 Clang。

M.M来自评论建议typedef应该工作,因为[basic.link]/4.3

命名类 ([

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

GCC可能会从字面上(?)解释它以排除using,尽管[dcl.typedef]/2说using引入的名称应该与typedef具有相同的语义。

令人惊讶的是,之前甚至在StackOverflow上被问过!

关于您的问题

他希望我使用 Persontype= struct{} 来定义结构;而不是结构的正常定义。

如果上面的文字是真的,这是一个相当奇怪的要求。这使得无法将不同的翻译单元与PersonType联系起来。我想知道背后的理由是什么,也许你不应该真正公开PersonType超出单个翻译单元?考虑咨询您的助教或教授。

最新更新