这似乎是 MSVC 的一个错误。使用形式的表达式T()
(就标准而言,这是一种显式类型转换)会产生指定类型的纯右值。
表达式T()
,其中是非数组完整对象类型或(可能是 cv 限定的)类型T
的简单类型说明符或类型名称说明符void
,创建指定类型的纯右值,它是值初始化的
const
由于非类纯右值不能具有 cv 限定类型的规则,只有非类类型才会被忽略:
类纯右值可以有 cv 限定类型;非类纯右值始终具有 cv 非限定类型。
所以T()
这里创建的临时对象应该const
也应该调用const
成员函数。
至于你什么时候用,为什么用std::add_const
,我们可以看一下它被列入提案的原因。它指出 , add_const
, add_volatile
,add_cv
和add_pointer
typeadd_reference
特征已从提案中删除,但在 Boost 用户投诉后又恢复了。
理由是这些模板都用作编译时函子,将一种类型转换为另一种类型 [...]
给出的例子是:
// transforms 'tuple<T1,T2,..,Tn>'
// to 'tuple<T1 const&,T2 const&,..,Tn const&>'
template< typename Tuple >
struct tuple_of_refs
{
// transform tuple element types
typedef typename mpl::transform<
typename Tuple::elements,
add_reference< add_const<_1> > // here!
>::type refs;
typedef typename tuple_from_sequence<refs>::type type;
};
template< typename Tuple >
typename tuple_of_refs<Tuple>::type
tuple_ref(Tuple const& t)
{
return typename tuple_of_refs<Tuple>::type(t);
}
您可以认为mpl::transform
将编译时元编程等同于函数指针作为其第二个模板参数 -add_reference<add_const<...>>
应用于Tuple::elements
. 这根本无法用const
.