我的代码有问题,甚至我的教授也不知道为什么会这样。
他希望我用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.cpp
和test.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
超出单个翻译单元?考虑咨询您的助教或教授。