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

Why give a typename template parameter a default value of 0 in C++?

精简版(没耐心看的):

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

我启用 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;
};

我的布尔常量结构:

template<lfBool Val>
struct lfBoolConstant
{
    static const lfBool Value = Val;    
};

typedef lfBoolConstant<true> lfTrueType;
typedef lfBoolConstant<false> lfFalseType;

我的类型特征结构(只是特化之一):

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;
}

抱歉格式不佳我正在我的手机上写这个phone。

长版(有耐心的请看一下,明白为什么代码不多):

所以,我正在度假,无法访问我的工作站或笔记本电脑,所以我想我会试试 AIDE,如果你不知道的话,它是 IDE android 可以编译C++。在家里,我正在设计一个包含 Boost 的游戏引擎,我想我会尝试创建类似于 Boost.Core 库中的 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的无名模板参数,即第二个参数声明基本上是 simple

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

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

template<typename T, lfInt = 0>

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

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

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

在上面的例子中我称之为V。该参数的名称未在模板中的任何地方使用,这就是为什么没有真正需要明确指定它的原因。这是一个虚拟参数,这也是它具有虚拟默认值的原因(您可以将 0 替换为 42 - 它也不会改变任何东西)。

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

在第一个模板参数声明中 - typename T - 它将 T 声明为模板 type 参数。在这个角色中关键字 typename 可以替换为关键字 class

template <class T, ...

在第二个声明中 - typename lfEnableIf<lfIsArithmetic<T>::Value>::Type = 0 - 它有一个次要目的 - 它只是告诉编译器 lfEnableIf<lfIsArithmetic<T>::Value>::Type 是一个 类型 从而将整个事情变成了 value 参数声明。在此角色中关键字 typename 不能替换为关键字 class.