如何实现可选模板参数?
我想要一个班级MyStruct<T1,T2,T3>
,允许只使用第一个或前两个参数。现在,处理MyStruct<T1,T2,T3>
的函数也应该以某种方式正确处理未使用的模板参数。
示例:
#include <iostream>
template<class T1, class T2, class T3>
struct MyStruct {
T1 t1; T2 t2; T3 t3;
MyStruct() {}
MyStruct(T1 const& t1_, T2 const& t2_, T3 const& t3_)
: t1(t1_), t2(t2_), t3(t3_) {}
};
template<class T1, class T2, class T3>
MyStruct<T1, T2, T3> myplus(MyStruct<T1, T2, T3> const& x,
MyStruct<T1, T2, T3> const& y) {
return MyStruct<T1, T2, T3>(x.t1 + y.t1, x.t2 + y.t2, x.t3 + y.t3);
}
int main() {
typedef MyStruct<int, double, std::string> Struct;
Struct x(2, 5.6, "bar");
Struct y(6, 4.1, "foo");
Struct result = myplus(x, y);
// (8, 9.7, "barfoo")
std::cout << result.t1 << "," << result.t2 << "," << result.t3;
}
现在我想更改代码,以便上面的main()
函数仍然有效,但以下内容也可以使用:
typedef MyStruct<std::string, int> Struct;
// result: ("barfoo", 5)
Struct result = myplus(Struct("bar", 2), Struct("foo", 3));
或者这个:
typedef MyStruct<int> Struct;
// result: (5)
Struct result = myplus(Struct(2), Struct(3));
我认为boost::tuple
使用类似的技巧,您可以使用boost::tuple<A>
,boost::tuple<A,B>
,boost::tuple<A,B,C>
,但我不确定他们是如何做到的。
答案 0 :(得分:3)
你可以在C ++ 11中使用可变参数模板(更难和更复杂的选项)来做到这一点;或者,您可以使用默认模板参数,如Boost.Tuple:
// boost/tuple/tuple/detail/tuple_basic.hpp
// -- null_type --------------------------------------------------------
struct null_type {};
//...
// - tuple forward declaration -----------------------------------------------
template <
class T0 = null_type, class T1 = null_type, class T2 = null_type,
class T3 = null_type, class T4 = null_type, class T5 = null_type,
class T6 = null_type, class T7 = null_type, class T8 = null_type,
class T9 = null_type>
class tuple;
答案 1 :(得分:3)
如果我找到你,你应该可以为你的模板传递默认参数:
template<class T1, class T2 = Default, class T3 = Default>
您可以替换Default
的任何类型。
答案 2 :(得分:1)
您可以故意制作“未使用”类型:
namespace detail { struct unused { }; }
template <typename T1, typename T2 = detail::unused, typename T3 = detai::unused>
struct MyStruct
{
typedef T1 type1;
typedef T2 type2;
typedef T3 type3;
explicit MyStruct(type1 const & t1,
type2 const & t2 = type2(),
type3 const & t3 = type3())
: x1(t1), x2(t2), x3(t3)
{ }
private:
type1 x1;
type2 x2;
type3 x3;
};