c++ - 模板争吵
问题描述
我遇到了一个问题,我创建了一个涉及模板的有点纠结的层次结构。结果是我不得不将一些代码放在错误的头文件中才能让它编译,现在编译很脆弱(如果只需要添加正确的函数,我不知道我是否可以继续编译这个项目.)
所以我正在寻找一种方法来解决这个问题,以便将代码很好地划分为适当的文件。
所以事不宜迟,代码如下:
TemplatedBase.h
template <typename T> struct TemplatedBase
{
T value;
void go();
};
派生的.h
struct Derived : public TemplatedBase<int>
{
void hello()
{
printf("HI %d\n", value);
}
};
template <typename T> void TemplatedBase<T>::go()
{
// TemplatedBase<T> NEEDS USE OF Derived!!
// So TemplatedBase<T>::go() is appearing here in Derived.h,
// that's the only way I could get it to compile and it seems really
// out of place here.
Derived der;
der.hello();
}
主文件
#include <stdio.h>
#include "Derived.h"
int main(int argc, const char * argv[])
{
Derived d;
d.go();
return 0;
}
有没有办法可以放入TemplatedBase<T>::go()
像这样的文件中TemplatedBase.cpp
?唉,它似乎不起作用(你会看到 Undefined symbol:TemplatedBase<int>::go()
至少在 XCode 中)。
解决方案
您可以通过在 cpp 文件中使用特定类型显式实例化模板来实现:
// TemplatedBase.cpp
#include "TemplatedBase.h"
#include "Derived.h"
template <typename T>
void TemplatedBase<T>::go()
{
// TemplatedBase<T> NEEDS USE OF Derived!!
// So TemplatedBase<T>::go() is appearing here in Derived.h,
// that's the only way I could get it to compile and it seems really
// out of place here.
Derived der;
der.hello();
}
template struct TemplatedBase<int>; // This will make it work but now you can only use `TemplatedBase<int>`
// More instantiations go here...
但我不建议这样做,因为这会限制您可以使用的类型TemplatedBase<T>
(您必须自己手动添加每种类型)。因此,请在成员函数中使用模板类型go()
(这里的技巧是模板参数不会立即评估):
// TemplatedBase.h
struct Derived; // Forward declaration
template <typename T>
struct TemplatedBase
{
T value;
void go()
{
go_impl();
}
private:
template <typename X = Derived>
void go_impl()
{
X der;
der.hello();
}
};
// Derived.h
#include "TemplatedBase.h"
struct Derived : public TemplatedBase<int>
{
void hello()
{
printf("HI %d\n", value);
}
};
注意:顺便说一句,从 C++20 开始,人们可以这样做:
// TemplatedBase.h
struct Derived; // Forward declaration
template <typename T>
struct TemplatedBase
{
T value;
void go()
{
[] <typename X = Derived>() {
X d;
d.hello();
}();
}
};
推荐阅读
- video - CDN 不允许我将 mov 视频格式转换为 mp4
- reactjs - #React 如何通过指定参数为某些参数传入函数值?
- python - 无法从 numpy 数组中检索值
- splunk - 如何在使用统计信息加入数据集之前过滤掉事件
- single-sign-on - IdentityServer - 将额外参数从 endsession 端点传递到 Logout
- excel - 仅当某个单元格已填充时才填充单元格
- excel - 如何从字符串中提取特定字符?
- firebase - Flutter Firebase 将两个集合数据合并到一个数组中并在小部件中显示数据
- docker - 在 docker 中构建二进制文件并挂载回主机
- node.js - 获取已知的 SSL 证书并将它们传递给 nodejs 请求