有很多方法可以解决这个问题。
选项 - 我
简单的方法是使用std::conditional 定义T2 的别名。其中如果T1 == int T2 将是double,所有其他类型 T2 将是int 的别名。 (See a demo)
#include <utility>
#include <type_traits> // std::conditional, std::is_same
template<typename T1>
struct Foo /* final */
{
static_assert(std::is_same<T1, int>::value || std::is_same<T1, float>::value, "NOT A VALID TYPE T1");
using T2 = typename std::conditional<std::is_same<T1, int>::value, double, int>::type;
using MyPair = std::pair<T1, T2>;
};
如果您想限制其他类型的类的实例化,请提供类的条件实例化或static_assert。
选项-II
您可以使用特征特化来定义T2 类型。 (See a demo)
#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>;
};
选项 - III
在c++17中,使用if constexpr可以决定在函数中返回哪个类型,并用它来知道T2的类型如下:
(See a demo)
#include <type_traits> // std::is_same_v
template<typename T1>
struct Foo /* final */
{
template<typename Type>
static constexpr auto typeHelper() noexcept
{
if constexpr (std::is_same_v<Type, int>)
return double{};
else if constexpr (std::is_same_v<Type, float>)
return int{};
}
using T2 = decltype(Foo<T1>::typeHelper<T1>()); // will select the proper one!
using MyPair = std::pair<T1, T2>;
};