在 C++ 中定义未命名结构时出错
Error defining an unnamed structure in c++
我的代码有问题,连我的教授都不知道为什么会这样。
他要我用 using 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
这是我的代码
main.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;
}
test.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;
}
}
和我的test.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
CMakeLists.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
都由预处理器处理,在处理类型时无关紧要。
所以,两个翻译单元(main.cpp
和test.cpp
)中的PersonType
实际上是指不同的类型。实际上,main.cpp
期望用一个 PersonType
找到 test(vector<PersonType> const &)
,而 test.cpp
只用另一个 PersonType
提供 test(vector<PersonType> const&)
,因此 link年龄错误。
这是 GCC 错误吗?
如果去掉模板并尝试一起编译以下两个翻译单元,您可以更好地看到错误:
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);
| ^~~~
但是,将 using Foo = struct {};
替换为 typedef struct {} Foo;
显然有效,并且从我的 GCC 切换到我的 Clang。
M.M 来自评论建议 typedef
应该工作因为 [basic.link]/4.3
a named class ([class.pre]), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes ([dcl.typedef]);
虽然 [dcl.typedef]/2 表示 using
引入的名称应该具有与 typedef
.
令人惊讶的是,it was even asked on Whosebug before!
关于您的问题
He wants me to define the structure with using Persontype= struct{}; and not a normal definition of a structure.
如果上面的文字是真的,那是一个很奇怪的要求。这使得 link 不同的翻译单元无法针对 PersonType
。我想知道背后的基本原理是什么,也许您不应该实际公开 PersonType
超出单个翻译单元?考虑咨询你的助教或教授。
我的代码有问题,连我的教授都不知道为什么会这样。
他要我用 using 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
这是我的代码
main.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;
}
test.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;
}
}
和我的test.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
CMakeLists.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
都由预处理器处理,在处理类型时无关紧要。
所以,两个翻译单元(main.cpp
和test.cpp
)中的PersonType
实际上是指不同的类型。实际上,main.cpp
期望用一个 PersonType
找到 test(vector<PersonType> const &)
,而 test.cpp
只用另一个 PersonType
提供 test(vector<PersonType> const&)
,因此 link年龄错误。
这是 GCC 错误吗?
如果去掉模板并尝试一起编译以下两个翻译单元,您可以更好地看到错误:
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);
| ^~~~
但是,将 using Foo = struct {};
替换为 typedef struct {} Foo;
显然有效,并且从我的 GCC 切换到我的 Clang。
M.M 来自评论建议 typedef
应该工作因为 [basic.link]/4.3
a named class ([class.pre]), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes ([dcl.typedef]);
虽然 [dcl.typedef]/2 表示 using
引入的名称应该具有与 typedef
.
令人惊讶的是,it was even asked on Whosebug before!
关于您的问题
He wants me to define the structure with using Persontype= struct{}; and not a normal definition of a structure.
如果上面的文字是真的,那是一个很奇怪的要求。这使得 link 不同的翻译单元无法针对 PersonType
。我想知道背后的基本原理是什么,也许您不应该实际公开 PersonType
超出单个翻译单元?考虑咨询你的助教或教授。