为什么在c++中给typename模板参数一个默认值0 ?



简短版本(如果你像我一样没有耐心,请阅读):

在c++中把typename模板参数设置为默认值0有什么用?

我的enable if struct:

/**
 * @brief Can be used to enable a template definition using a boolean value
 */
template<lfBool Condition>
struct lfEnableIf
{ };
template<>
struct lfEnableIf<true>
{
   typedef lfInt Type;
};

My boolen constant struct:

template<lfBool Val>
struct lfBoolConstant
{
    static const lfBool Value = Val;    
};
typedef lfBoolConstant<true> lfTrueType;
typedef lfBoolConstant<false> lfFalseType;

我的类型trait结构(只是一个特化):

template <typename NumT> struct lfIsArithmetic : lfFalseType{};
template <> struct lfIsArithmetic<lfChar> : lfTrueType{};

最后是我的用法:

template<typename T, typename lfEnableIf<lfIsArithmetic<T>::Value>::Type = 0>
struct Test
{
    static void print()
    {
        std::cout << "OK!" << std::endl;
    }
};
int main()
{
    Test<lfFloat>::print();
    Test<lfBool>::print();
    return 0;
}

对不起,格式不太好,我是在手机上写的。

长版本(请阅读如果你有耐心,这样你就明白为什么没有太多的代码):

所以,我在度假,不能访问我的工作站或笔记本电脑,所以我想我会尝试AIDE,如果你不知道这是一个android的IDE,可以编译c++。在家里,我正在设计一个包含Boost的游戏引擎,我想我会尝试创建一些类似于Boost中的enable_if结构的东西。核心库。我得到了它大部分工作,但它不会编译,除非我在模板中设置启用if结构,我启用默认为0!这就是您对Boost enable_ifdisable_if模板所做的。那么,在c++中将typename模板参数设置为默认值0有什么用呢?

谢谢!

这一行

template<typename T, typename lfEnableIf<lfIsArithmetic<T>::Value>::Type = 0>

声明了一个命名模板类型参数T和一个命名模板类型lfEnableIf<lfIsArithmetic<T>::Value>::Type参数,即第二个参数声明基本上是简单

的一个更复杂的版本。
template <int N = 0> struct S {};

当满足启用条件时,类型lfEnableIf<lfIsArithmetic<T>::Value>::Type解析为类型lfInt,这意味着在这种情况下,整个内容相当于

template<typename T, lfInt = 0>

然而,由于第二个模板参数的类型是依赖模板lfEnableIf嵌套类型,因此需要使用关键字typename告诉编译器成员Type实际上引用的是类型,而不是其他类型(即消除歧义)。

同样,模板的第二个参数是无名的,但是如果您愿意,可以给它一个名字。它不会改变任何东西

template<typename T, typename lfEnableIf<lfIsArithmetic<T>::Value>::Type V = 0>

在上面的例子中,我称之为V。该参数的名称不会在模板的任何地方使用,这就是为什么实际上不需要显式指定它的原因。这是一个虚拟参数,这也是它有一个虚拟默认值的原因(你可以用42代替0——它也不会改变任何东西)。

在这种情况下,关键字typename在模板的两个参数声明之间创建了误导性的相似性。实际上,在这些参数声明中,关键字typename服务于两个非常非常不同的不相关的目的。

在第一个模板参数声明typename T中,它将T声明为模板类型参数。关键字typename可以替换为关键字class

template <class T, ...

在第二个声明typename lfEnableIf<lfIsArithmetic<T>::Value>::Type = 0中,它有一个次要的目的——它只是告诉编译器lfEnableIf<lfIsArithmetic<T>::Value>::Type是一个类型,从而把整个东西变成一个参数声明。关键字typename不能替换为关键字class

相关内容

  • 没有找到相关文章

最新更新