【问题标题】:C++11 - Distinguishing rvalue pointersC++11 - 区分右值指针
【发布时间】:2011-07-17 20:07:51
【问题描述】:

如何将变量区分为编译器构造的字符串?

例如,右值 "Hello, World" 的类型为 const char*const char* 本身并不意味着不能更改指针。 char* const 指针无法更改,但这不是编译器构造的。

这是否意味着,对于任何拥有const char* 的容器,数据应该通过C++ 的移动语义以外的方式复制?有什么方法可以移动编译器构造的字符串,而不管其他所有字符串吗?

例如,在 GCC 4.5.2 中,返回类型为 int 而不是 int& 的方法被视为返回 int&&。我不知道实际的标准是不是应该是这样的,但GCC暂时就是这样做的。

编辑:为了澄清,我的意思是应该复制指针指向的实际内存。这意味着必须分配新的内存并将指针中的数据复制到新位置。

【问题讨论】:

  • 我不太了解“编辑”。你能澄清一下吗?

标签: c++ string c++11 rvalue-reference move-semantics


【解决方案1】:

这是否意味着,对于任何包含 const char* 的容器,数据应该通过 C++ 的移动语义以外的方式复制?

表示指针被复制。不多也不少。必须复制指针,容器才能工作。

【讨论】:

    【解决方案2】:

    "Hello, World" 不是const char* 类型的。它是const char[13] 类型,它是一个左值,而不是一个右值。

    当您在将"Hello, World" 隐式转换为指向其初始元素的const char* 的上下文中使用"Hello, World" 时,生成的指针是一个右值(因为它是一个由隐式转换产生的临时对象。

    例如,在 GCC 4.5.2 中,返回类型为 int 而不是 int& 的方法被视为返回 int&&

    如果您调用按值返回的函数(例如,int),则该函数调用表达式是一个右值表达式。如果您调用返回左值引用的函数(例如,int&),则该函数调用表达式是左值表达式。

    如何将变量区分为编译器构造的字符串?

    你不能,真的:"Hello, World" 和你可能声明的任何其他const char[13] 之间没有区别。

    至于在标准库容器中存储const char*s 或任何其他指针类型,如std::vector,容器不会接触指向的数据:容器只是要创建、移动、复制,并销毁指针。

    如果您需要管理指向的数据,您需要自己编写一个类来管理指向的对象(很像智能指针类)。编写一个类来管理这样的资源的习惯用法称为“资源获取即初始化”(RAII)或“范围绑定资源管理”(SBRM)。

    【讨论】:

    • Stramge:gcc 4.5 为f("abcd")f(ac) 打印“rvalue const char*”。
    • @GMan:这很有趣:它得到了f(a),不过,这很奇怪。 Visual C++ 2010 SP1 为f(new char) 打印“lvalue char*,这显然是错误的。它还为所有三个左值数组调用打印lvalue char const*,并拒绝编译两个右值数组调用。我展示的结果来自 Clang 3.0(Trunk 127530),根据最新的 C++0x 草案,我认为它们是正确的;不过,我会深入研究以确保。
    • @James:是的,那个 MSVC 错误咬了我here。但是,是的,我相信你的解释是正确的。不过,我懒得查找错误报告。 :x :)
    • @GMan:实际上,我不太确定了......“无转换”在 13.3.3 中与“左值到右值转换”和“数组到-指针转换,”所以我认为 g++ 行为可能是正确的,也许。当我读到第 13 条时,我的头很痛,今天是圣帕特里克节,所以我可能会在明天之前继续研究。
    猜你喜欢
    • 2016-06-10
    • 2012-03-23
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多