有没有办法将模板参数“捆绑”在一起以避免重复?
我有几个类和函数都使用相同的三个模板参数。拥有一次使用每个类/函数的函数并不罕见。结果代码非常快速地变得非常混乱。 有没有更简洁的方法来编写这段代码?
// ContextFactory is a pointer to functions that instantiate objects that are subtypes of MetricContext
template<typename VertexID, typename EdgeMembershipType, typename SetBitmap>
using ContextFactory = MetricContext <VertexID, EdgeMembershipType, SetBitmap> *(*)(const char *);
template<typename VertexID, typename EdgeMembershipType, typename SetBitmap>
static vector<ContextFactory<VertexID, EdgeMembershipType, SetBitmap>> buildCFList() {
vector<ContextFactory<VertexID, EdgeMembershipType, SetBitmap>> answer;
answer.push_back(MetricContext<VertexID, EdgeMembershipType, SetBitmap>::template make<NeoContext<VertexID, EdgeMembershipType, SetBitmap >>);
return answer;
};
请注意,此函数的近一半是字符串<VertexID, EdgeMembershipType, SetBitmap>>
的重复,但每次使用此字符串都适用于不同的类或函数,因此我认为别名不起作用。
(如果有帮助,此函数的目的是创建一个指向函数的指针数组,这些函数将创建MetricContext<VertexID, EdgeMembershipType, SetBitmap>>
答案 0 :(得分:5)
比@ Quentin更具体的方法是让你的模板依赖于一个参数 - 预计会有VertexID
,EdgeMembershipType
和SetBitmap
的typedef。
// ContextFactory is a pointer to functions that instantiate objects that are
// subtypes of MetricContext
template<typename Types>
using ContextFactory = MetricContext <Types> *(*)(const char *);
template<typename Types>
static vector<ContextFactory<Types>> buildCFList() {
vector<ContextFactory<Types>> answer;
answer.push_back(MetricContext<Types>::template make<NeoContext<Types>>);
return answer;
};
请注意,当您想要使用其中一个typedef时,您需要使用例如:typename Types::VertexID
。
(理想情况下,您会为模板参数提供比Types
更好的名称。)
答案 1 :(得分:4)
是的,这是可能的。让我们定义一个小助手类来保存类型列表:
template <class... > struct pack { };
一个元函数,用pack
中的内容实例化模板:
template <template <class... > class T, class P>
struct unpack_;
template <template <class... > class T, class... P>
struct unpack_<T, pack<P...>> {
using type = T<P...>;
};
template <template <class... > class T, class P>
using unpack = typename unpack_<T, P>::type;
我们现在可以存储和使用我们的参数包:
template <class A, class B, class C>
struct Foo { };
using Params = pack<int, float, double>;
unpack<Foo, Params> f; // f is a Foo<int, float, double>
答案 2 :(得分:1)
如果您正在使用C ++ 11,则可以使用std :: tuple将变量合并为一个。
理解相同的更简单的例子可以是
template <typename A, typename B, typename C>
void fn() {
typedef std::tuple<A,B,C> myTuple;
myTuple tpl;
cout<<sizeof(std::get<0>(tpl))<<endl;;
cout<<sizeof(std::get<1>(tpl))<<endl;
cout<<sizeof(std::get<2>(tpl))<<endl;
}
int main() {
fn<int,char,long>();
return 0;
}
针对您的问题特有的问题,您可以创建元组的向量
template <typename A, typename B, typename C>
void fn() {
using mycomb = std::tuple<A,B,C>;
vector<mycomb> v1;
v1.push_back(make_tuple(10,'c',20.0));
}
通过这种方式,您不需要重复相同的操作。元组getter函数起初有点尴尬。上面的cout
示例演示了如何访问元组参数
希望这有帮助