为什么在 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_if
和 disable_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
.
精简版(没耐心看的):
在 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_if
和 disable_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
.