c++ - 如何使用可变参数模板在 C++ 中概括对象创建?
问题描述
我正在尝试在 C++ 中创建一个通用工厂方法,它可以创建许多(但数量有限)对象之一的实例。每个对象都需要不同类型的参数来构造,因此我希望该方法能够以某种方式推断所需的类型,并且不希望用户明确指定它。
这是一些代码来说明我正在尝试做的事情:
#include <iostream>
using namespace std;
class A {
public:
A(int x, int y) {
cout << "A(" << x << ", " << y << ")\n";
}
};
class B {
public:
B(float a, float b) {
cout << "B(" << a << ", " << b << ")\n";
}
};
template<typename T, typename... Ts>
T * Make(Ts... vs) {
puts(__PRETTY_FUNCTION__); // __FUNCSIG__ or __PRETTY_FUNCTION__
return new T{ vs... };
}
现在,比如说,main
函数中的代码可以创建类型的对象A *
并B *
通过调用Make
:
A *a = Make<A>(3, 4);
B *b = Make<B>(3.14f, 6.28f);
有没有一种方法可以扩展此代码以使其他函数能够调用Make
,而无需明确指定它们是否A *
需要B *
的实例?例如,
A * a = Make(3, 4); // (int, int)
B * b = Make(3.14f, 6.28f); // (float, float)
我知道函数模板是使用参数类型推导来实例化的,而返回类型不参与其中。但是,编译器不会进行任何类型转换。所以Make(int, int)
绝对是一个不同的实例Make(float, float)
,我希望能够利用它来将函数定义映射到正确的返回类型。
这是我尝试过的:
定义显式实例化
template A * Make(int x, int y);
定义专业
template<> A * Make<A, int, int>(int x, int y);
两者都没有按预期工作。关于如何实现这一点的任何想法?
解决方案
I wrote a Maker
helper template that registers which classes are allowed, although I don't exactly know how to disable the base template:
template <typename... Ts>
struct Maker {
using type = void;
};
template <>
struct Maker<int, int> {
using type = A;
};
template <>
struct Maker<float, float> {
using type = B;
};
template<typename... Ts, typename T=typename Maker<Ts...>::type>
T * Make(Ts... vs) {
puts(__PRETTY_FUNCTION__); // __FUNCSIG__ or __PRETTY_FUNCTION__
return new T{ vs... };
}
int main() {
A * a = Make(3, 4); // (int, int)
B * b = Make(3.14f, 6.28f); // (float, float)
}
推荐阅读
- python - 对于文件 json 中的键和值
- java - 慢 HikariDataSource.getConnection() 在低流量时慢,在大流量时快
- r - 如何编写一个 r 块来加载 tidyverse?
- pyspark - 将数据框写入CSV文件时如何避免生成crc文件和SUCCESS文件?
- css - 使用 SVG feTurbulence 作为过滤器会导致 Safari 出现奇怪的渲染问题
- javascript - 有谁知道如何使观看状态与 url 一起工作?
- git - 如何在 git diff 中明确引用当前未提交的仓库状态
- sql - 存储过程插入日期格式的问题
- dropbox - 检查文件是否存在 (Dropbox API v2)
- java - 如何删除队列中的第二个元素?