繁体   English   中英

const临时从模板类型和为什么使用std :: add_const?

[英]Const temporary from template type and why use std::add_const?

以下代码摘自cppreference.com

#include <iostream>
#include <type_traits>

struct foo
{
    void m() { std::cout << "Non-cv\n"; }
    void m() const { std::cout << "Const\n"; }
};

template <class T>
void call_m()
{
    T().m();
}

int main()
{
    call_m<foo>();
    call_m<std::add_const<foo>::type>();
}

但是,使用VC ++ 2012年11月的CTP编译时,输出为

非CV

非CV

而不是预期的:

非CV

常量

此外,以下两个陈述之间的区别是什么:

call_m<const foo>();

call_m<std::add_const<foo>::type>();

这似乎是MSVC的一个错误。 使用T()形式的表达式T()就标准而言,这是一种显式类型转换)会产生指定类型的prvalue。

表达式T() ,其中T是非数组完整对象类型的简单类型说明符类型名称说明 ,或者(可能是cv限定的) void类型,创建指定类型的prvalue,它是值 -初始化

由于非类prvalues不能具有cv限定类型的规则,因此只有非类类型才会忽略const

类prvalues可以具有cv限定类型; 非类prvalues始终具有cv不合格类型。

所以这里由T()创建的临时对象应该是const ,因此应该调用const成员函数。

至于何时以及为什么要使用std::add_const ,我们可以看看它包含在提案中的原因。 它声明add_constadd_volatileadd_cvadd_pointeradd_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表示。

从我记得的内容如下,你可以在函数声明中写出3个consts(3是目的数)。

返回类型之前,函数及其参数之后,以及参数本身。

函数签名末尾的const表示函数应该假定它所属的对象是const。 实际上,它意味着您要求编译器检查成员函数是否以任何方式更改对象数据。 这意味着要求编译器检查它是否不直接更改任何成员数据,并且它不会调用任何本身不保证它不会更改对象的函数。

在返回类型之前意味着函数要返回的东西应该是const。

const参数表示该参数不能更改。

所以区别在于,第一次调用不是const,所以它转到“非cv”,第二次调用是const,因此转到“const”。

我想到为什么VC ++两次都使用相同的函数是call_m显式调用T()。m()认为它不应该转到const。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM