用于选择第一个定义类型的模板表达式



我需要一个模板表达式,如果定义了第一个参数,则选择第一个参数类型,否则选择第二个参数类型。

select<int, float>::type               // type evaluates to int
select<an_undefined_type, float>::type // type evaluates to float

。并且该解决方案必须与 C++03 和 Boost 1.33.1 一起使用:(

我的目标是接受intboost::optional<int>作为函数模板参数T,因此我可以执行以下操作:

template<typename T>
void fn(T& t)
{
int x = std::numeric_limits<select<T::value_type, T>::type>::digits;
}

因为boost::optional<int>::value_type是定义的。

C++11解决方案也值得赞赏。

我看不到通过模板专业化来做到这一点的方法,因为我试图专注于概念而不是类型。基本上,我需要一种与any_integer概念相匹配的专业化和一个与boost::optional<any_integer>概念相匹配的专业化。

我想使用 C++11 我可以通过以下方式实现这个特定目标:

std::conditional<std::is_integral<T>::value, T, T::value_type>::value

但我没有C++11,我想要更通用的解决方案。

我认为您无法实现所需的确切符号。但是,我认为您可以使用稍微不同的符号来实现您在语义上所追求的内容。您当前符号的问题

int x = std::numeric_limits<select<T::value_type, T>::type>::digits;

select<T0, T1>期望两种类型,即,对存在的类型的要求不在select<T0, T1>模板上,而是在调用它的函数上。我会改变它的方法是使用

int x = std::numeric_limits<select<typename get_value_type<T>::type, T>::type>::digits;

现在需要做的只是有一个get_value_type<T>,如果存在,它会生成嵌套类型,如果到达那里,某些类型select<T0, T1>将被忽略,例如,void(或自定义标记类型)。get_value_type<T>模板应该相当简单(我看到了 Dirk Holsopple 的答案,但我无法让它工作):

template <typename T>
struct has_value_type
{
typedef char (&true_type)[1];
typedef char (&false_type)[2];
template <typename D> static true_type test(typename D::value_type*);
template <typename D> static false_type test(...);
enum { value = sizeof(test<T>(0)) == 1 };
};
template <typename T, bool = has_value_type<T>::value >
struct get_value_type
{
typedef T type; // EDIT
};
template <typename T>
struct get_value_type<T, true>
{
typedef typename T::value_type type;
};

显然,您可能希望定义略有不同的类型特征,以便您可以使用类似

int x = std::numeric_limits<typename get_type<T>::type>::digits;

如果有value_type,这将返回嵌套类型,否则T类型。

相关内容

最新更新