既然你可以把积分值作为模板参数并对其执行算术,什么是落后的boost :: MPL :: INT _ <>和其他整型常量的动机是什么? 这是否动机仍然适用于C ++ 11?
Answer 1:
你可以把积分值作为模板参数,但你不能把两种类型和非类型模板参数与一个单一的模板。 长话短说,治疗非类型模板参数 类型允许他们对事物内MPL无数使用。
例如,考虑一元函数find
与类型的作品,并寻找一个序列中平等的类型。 如果您想与非类型模板参数使用它,你将需要重新实现新的算法,“过载”,一个find_c
您具有手动指定的积分值的类型 。 现在想象你想让它与混合整数类型作为语言的其余部分没有工作,或者你想混用类型和非类型 ,你会得到“重载”也恰巧是更难,因为你必须使用爆炸到处指定每个非类型参数的类型。
这种动机确实还适用于C ++ 11。
这种动机仍适用于C ++ y和任何其他版本,除非我们有一些新的规则,允许非类型模板参数转换成键入模板参数。 举例来说,当你使用5
和模板请求类型与初始化它std::integral_constant< int, 5 >
代替。
Answer 2:
tldr; 编码值作为一种允许它比简单的价值远远更多的地方使用。 您可以在超载的类型,你不能超载值。
K-假面舞会的答案是伟大的。
还有,我认为是相关的,虽然别的东西。 积分常数类型不仅可以作为模板参数有用,它们可以作为函数的参数和函数的返回类型有用的(在我的例子使用C ++ 11种,但同样的道理也适用于Boost的那些早于它们):
template<typename R, typename... Args>
std::integral_constant<std::size_t, sizeof...(Args)>
arity(R (*)(Args...))
{ return {}; }
这个函数有一个函数指针,并返回一个类型告诉你的参数的函数所取的数量。 之前我们已经constexpr
功能有没有办法来调用的常量表达式中的函数,所以要问这样的问题“有多少争论,这种功能型走?” 你需要返回一个类型 ,并从中提取出的整数值。
即使constexpr
的语言(这意味着上述功能可能只是return sizeof...(Args);
以及整数值会在编译时使用)仍然有整型常量类型,例如标签调度好用途:
template<typename T>
void frobnicate(T&& t)
{
frob_impl(std::forward<T>(t), std::is_copy_constructible<T>{});
}
此frob_impl
功能可以基于被重载integer_constant<bool, b>
类型作为其第二个参数传递:
template<typename T>
void frob_impl(T&& t, std::true_type)
{
// do something
}
template<typename T>
void frob_impl(T&& t, std::false_type)
{
// do something else
}
您可以尝试通过将布尔模板参数做类似的事情:
frob_impl<std::is_copy_constructible<T>::value>(std::forward<T>(t));
但它不是可以部分专门函数模板,所以你不能让frob_impl<true, T>
和frob_impl<false, T>
做不同的事情。 超载的布尔常量的类型让你轻松根据的“是拷贝构造”特征值做不同的事情, 那就是仍处于C ++ 11是非常有用的。
其中常数是有用的地方是使用SFINAE实施特质。 在C ++ 03传统的方法是有重载函数返回两种类型的具有不同尺寸(例如, int
和含有两个一个结构int
或多个)和测试“值”与sizeof
。 在C ++ 11的函数可以返回true_type
和false_type
远远更具表现力,例如,测试一个性状“不这种类型都称为成员foo
?” 可以使功能表示肯定结果恢复true_type
,使功能指示阴性结果的回报false_type
,有什么能比这更清楚了吗?
作为一个标准库实施者我做出非常频繁使用的true_type
和false_type
,因为很多编译时的“问题”有真/假答案,但是当我想测试的东西,可以有两个以上的不同的结果,我会用其他的特integral_constant
。