c++ - c ++模板,两个不同文件中的重复类名,静态初始化
问题描述
我有两个具有相同类名的不同文件(这里:A)。类用于模板特化。专用模板用于静态对象初始化。我希望编译器使用本地类来解决模板,但结果表明它需要两倍的相同专业化。
问题是:如何防止创建这样的代码(可能是一些编译器设置来检测这个),因为它真的很难调试?
------- template.h
template <typename T>
void Test() {
T* t = new T();
delete t;
}
------- classA1.cpp
#include <iostream>
#include "template.h"
class A {
public:
A() {
std::cout << "Hello I'm class A(1)" << std::endl;
}
};
struct Tester1 {
Tester1() {
Test<A>();
}
};
static Tester1 tester1;
------- classA2.cpp
#include <iostream>
#include "template.h"
class A {
public:
A() {
std::cout << "Hello I'm class A(2)" << std::endl;
}
};
struct Tester2 {
Tester2() {
Test<A>();
}
};
static Tester2 tester2;
------- main.cpp
#include <iostream>
int main() {
std::cout << "Hello from main!" << std::endl;
return 0;
};
结果:
Hello I'm class A(1)
Hello I'm class A(1)
Hello from main!
解决方案
关于一个定义规则:
在任何一个翻译单元中只允许对任何变量、函数、类类型、枚举类型或模板进行一个定义(其中一些可能有多个声明,但只允许一个定义)。
一个且只有一个类的定义需要出现在任何翻译单元中,其中该类的使用方式要求它是完整的。
一个程序中可以有多个以下各项的定义:类类型 [...] 只要满足以下所有条件:
[...] - 每个定义都包含相同的标记序列 [...]
你打破了 ODR。对于类类型,如果您破坏 ODR,编译器不会抱怨,但它希望您使用相同的标记序列定义该类。由于编译器期望您的所有同名类定义都是相同的,因此它将只选择其中一个进行链接,然后您将获得您所获得的行为。例如,当您定义两个具有相同名称但定义不同的内联函数时,也会发生同样的情况,只会选择其中一个定义。
推荐阅读
- php - 使用 Swift trough php 将文件上传到 AWS
- python - 有没有办法逐个单元格比较两个 csv 文件?
- latex - 我如何在 LaTeX 中写这个符号?
- adaptive-cards - 来自变量/数据源的自适应卡片和选择集
- python - 将空列表附加到字典
- javascript - 从服务器代码向谷歌广告发送转化数据
- windows - 在powershell中添加包含空格的进程名称
- python - 我的功能没有正确暂停或正确检测鼠标点击
- android - Android -gradle task -Azure devops - Pipeline No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi
- r - R循环将相同的功能应用于多个数据帧