我在之前的问题后继续研究了一下引用限定符。
给定下面的代码示例:
#include <iostream>
#include <string>
#include <utility>
struct A {
std::string abc = "abc";
std::string& get() & {
std::cout << "get() &" << std::endl;
return abc;
}
std::string get() && {
std::cout << "get() &&" << std::endl;
return std::move(abc);
}
std::string const& get() const & {
std::cout << "get() const &" << std::endl;
return abc;
}
std::string get() const && {
std::cout << "get() const &&" << std::endl;
return abc;
}
};
int main()
{
A a1;
a1.get();
const A a2{};
a2.get();
A().get();
const A a3{};
std::move(a3).get();
}
输出结果如下:
get() &
get() const &
get() &&
get() const &&
这段代码可以在clang和gcc 4.9.1(但不包括4.9.0)上编译运行。 点击此处查看演示。
一般来说,这是一段代码(样例仅用于展示代码的编译和运行情况)。
- 一个方法被标记为
const &&
,意味着什么?
该方法无法修改对象的内容(它是const
),尝试从const &&
方法中返回std::move(abc);
实际上并没有移动std::string
。 假设你希望能够修改对象,因为它是一个右值,而且不会存在很长时间。 如果删除了const &&
限定符,代码std::move(a3).method()
将绑定到const &
限定符方法,这是有道理的。
- 如果方法被标记为
const &
和const &&
,是否会有任何暗示的语义区别?换句话说,实现会有何不同或为什么需要两者? std::string
真正能够从临时对象中“移动”出来吗?- 在这种情况下,“std::string get() const &&”的“规范”签名是什么?
const
,所以无法这样做。对于const
右值对象访问,将调用const &
限定的方法。 - Potatoswatteroptional
等指定的。&&
和const&&
方法具有相同的效果(n4082,第5.3.5段第11、20等)。值得注意的是,GCC在给定const rvalue时选择正确方法存在问题,但clang没有。我认为这里的重点是一般情况下没有用处,但还有一些特殊情况需要考虑(然后仔细考虑为什么需要它)。 - Niall