C++ 模板表达式以选择第一个定义的类型

C++ 模板表达式以选择第一个定义的类型,c++,template-meta-programming,C++,Template Meta Programming,我需要一个模板表达式,如果定义了第一个参数,则选择第一个参数类型,否则选择第二个参数类型 select<int, float>::type // type evaluates to int select<an_undefined_type, float>::type // type evaluates to float 由于定义了boost::optional::value\u类型 C++11解决方案也很受欢迎 我看不到模板专门化的方法,因为

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

select<int, float>::type               // type evaluates to int
select<an_undefined_type, float>::type // type evaluates to float
由于定义了
boost::optional::value\u类型

C++11解决方案也很受欢迎

我看不到模板专门化的方法,因为我试图专门化的不是类型,而是概念。基本上,我需要一个与
any_integer
概念匹配的专门化和一个与
boost::optional
概念匹配的专门化

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

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

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

我认为你无法实现你想要的精确符号。然而,我认为您可以使用稍微不同的符号来实现您在语义上所追求的。当前符号的问题

int x = std::numeric_limits<select<T::value_type, T>::type>::digits;
显然,您可能希望定义稍微不同的类型特征,以便可以使用

int x = std::numeric_limits<typename get_type<T>::type>::digits;
intx=std::numeric\u limits::digits;

如果存在
value\u type
T
类型,则返回嵌套类型。

仅接受可选值就足够了吗?而且,C++11已经有一年的历史了;没有它是很奇怪的,除非你正在开发一些没有更新/维护编译器的非常特定的体系结构。我正在研究这个问题,可能会有答案:我想这就是答案:@Griwes:恐怕你生活在一个独角兽世界。在我工作的公司,我们已经从gcc 3.4.2过渡到gcc 4.3.2有几年了。只要这一转变没有结束,我们就不会继续到另一个版本。C++11对我们来说是未来几年。。。从我在网上收集的信息来看,我可能很幸运,因为gcc 4.3.2并没有那么老。@MatthieuM.,这(即人类的愚蠢)可能是我现在想在一家大学工作的原因,而不是在一些使用被上帝抛弃的编译器版本的公司工作。。。不过,OP并没有回答我最初评论中更重要的部分。答案被接受,谢谢迪特玛!(第15行有一个打字错误,
typedef void type
应该是
typedef T type
)也编辑了用法示例,以前是
int x=std::numeric\u limits::digits用于说明我在上述示例中描述的内容的用法示例。在下面的示例中,我指出,根据您想使用它做什么,这并不是真正必要的:因为您的即时应用程序比您最初要求的更具体,所以可以使用更具体的解决方案来简化它。哦,我明白了,我还原了使用示例。另外,感谢您指出“对要显示的类型的要求不在模板上,而是在调用它的函数上。”
int x = std::numeric_limits<select<typename get_value_type<T>::type, T>::type>::digits;
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;