这就是我迄今所做的尝试:
下面是我的代码:
template<typename T1>
struct Foo {
template<typename T2>
using MyPair = std::pair<T1, T2>;
using MyPairs = std::vector<MyPair>;
Foo() {
//if T1 is an int, then I want T2 to be a double.
//if T1 is a float, then I want T2 to be an int.
}
};
如果t1
是int
,我希望t2
是double
。 如果t1
是float
,我希望t2
是int
。
我怎么能做到这一点?
此解决方案没有嵌套模板,但如您所期望的那样工作:
template<typename T1,
class = std::enable_if_t<std::is_same<T1, int>::value || std::is_same<T1, float>::value>>
struct Foo {
typedef typename std::conditional<std::is_same<T1, int>::value, double, int>::type T2;
using MyPair = std::pair<T1, T2>;
using MyPairs = std::vector<MyPair>;
MyPairs elements;
Foo() {
//if T1 is an int, then I want T2 to be a double.
//if T1 is a float, then I want T2 to be an int.
std::cout << typeid(T2).name() << std::endl;
}
};
int main()
{
Foo<int> f;
f.elements.push_back (std::make_pair(1.4, 2.3));
std::cout << f.elements[0].first << ", " << f.elements[0].second << std::endl;
return 0;
}
输出:
d
1, 2.3
解决这个有很多方法。
简单的方法是使用std::conditional
定义T2
的别名。 其中,如果t1==int
,则t2
将是double
,在所有其他情况下,t2
将是int
的别名。
#include <type_traits> // std::conditional
using T2 = typename std::conditional<std::is_same_v<T1, int>, double, int>::type;
如果要限制其他类型的类实例化,请提供类的条件实例化或static_assert
。
您可以使用traits专门化来定义T2
类型。 (参见演示)
#include <vector>
#include <utility>
// base template!
template <typename T1> struct helper_traits;
template <> // when helper_traits<`T1 == int`> then `T2 == double`
struct helper_traits<int> final { using T2 = double; };
template <> // when helper_traits<`T1 == float`> then `T2 == int`
struct helper_traits<float> final { using T2 = int; };
template<typename T1>
struct Foo /* final */
{
using T2 = typename helper_traits<T1>::T2; // will select the proper one!
using MyPair = std::pair<T1, T2>;
using MyPairs = std::vector<MyPair>;
Foo()
{
// ....
}
};