Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I've been digging around ref-qualifiers a bit, following on a previous question.

Given the code sample below;

#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();
}

And the output is as you would expect:

get() &
get() const &
get() &&
get() const &&

This compiles and runs with clang and gcc 4.9.1 (not 4.9.0 though). Live sample here.

In general code (the sample is there to see how the code compiles and runs).

  • What would the purpose of the const && ref-qualifier on a method be?

The method is unable to modify the contents on the object (it is const), an attempt to return std::move(abc); from the const && method doesn't actually move the std::string at all. Presumably you would want to be able modify the object, since it's an r-value and won't be around for long. If the const && qualified method were to be removed, the code std::move(a3).method() would bind to the const & qualified method, which would make sense.

  • What, if any, would the implied semantic difference be between a method qualified as const & and one qualified as const &&? I.e. how would the implementation vary or why would you want both?
  • Would the std::string truely be able to be "moved" out of the temporary object?
  • What would a "canonical" signature look like for std::string get() const && in this case?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
348 views
Welcome To Ask or Share your Answers For Others

1 Answer

On the usefulness of const&&... (in general)

The usefulness of the const&& qualifier on the member method is minimal at best. The object cannot be modified in the same manner as a && method would allow it to be modified; it is const after all (as noted, mutable does change this). So we will not be able to rip out its guts, since the temporary is expiring anyway, as we would in something akin to a normal move.

In many ways the usefulness of the const&& may be best evaluated in the context of how useful an object of type const T&& is to begin with. How useful is a const T&& function argument? As pointed out in another answer (to this question) here, they are very useful in declaring functions deleted, e.g. in this case

template <class T> void ref (const T&&) = delete;

to explicitly disallow objects of prvalue and xvalue value category types from being used with the functions, and const T&& does bind to all prvalue and xvalue objects.

What is the usefulness of const&& method qualifier?

It is interesting to note that in the proposal C++ library extensions, optional, § 5.3, includes overloads, e.g.

constexpr T value() const &&;

that are qualified as const&& and are specified to perform the same action as the && alternative.

The reason I can infer for this case; is that this is for completeness and correctness. If the value() method is called on an rvalue, then it performs the same action independent of it being const or not. The const will need to be dealt with by the contained object being moved or the client code using it. If there is some mutable state with the object being contained, then that state can legitimately be changed.

There may well still be some merit in this; in no particular order...

  • To declare it = delete to prohibit the method's use on prvalues and xvalues.
  • If the type has mutable state and the qualifier makes sense (possibly in addition to the other qualifiers) in the target environment, consider it.
  • If you are implementing a generic container type, then for completeness and correctness, consider adding it and performing the same action as the && method. Advice here is sort from the standard library (and its extensions).

What would a "canonical" signature look like for a const&& qualified method?

Since the method will be performing the same action as the && method, I would advocate that the signature matches the && signature.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...