rvalue квалифицированный метод и константное выражение - PullRequest
0 голосов
/ 27 ноября 2018

Как я могу сделать const rvalue естественным способом?

Вот простой пример:

struct A {
  void f() &&{}                 // 1
  constexpr bool f() const &{return true;}  // 2
  constexpr bool f() const &&{return true;} // 3 really usefull?
};

int main() {
    static_assert(A{}.f()); // does not compile because call 1 instead of 3
    constexpr A a;
    static_assert(a.f());
}

Почему первый static_assert() вызывает 1 вместо 3?

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Вопрос в том, как заставить объект rvalue работать с константным выражением

Другим способом может быть функция constexpr, возвращающая A const

#include <iostream>

struct A
 {
   std::size_t f() & { return 1u; }
   std::size_t f() && { return 2u; }
   constexpr std::size_t f() const & {return 3u; }
   constexpr std::size_t f() const && {return 4u; } 
 };

constexpr A const foo ()
 { return {}; }

int main()
 {
   static_assert( foo().f() == 4u, "!" );      
 }
0 голосов
/ 27 ноября 2018

Может быть, это то, что вы хотите?

struct A {
    constexpr bool f() &&{return true;}                 // 1
    constexpr bool f() const &{return true;}  // 2
    constexpr bool f() const &&{return true;} // 3 really usefull?
};

int main() {
    static_assert(A{}.f()); // does not compile because call 1 instead of 3
    constexpr A a;
    static_assert(a.f());
}
0 голосов
/ 27 ноября 2018

Проблема в том, что A{} не дает вам const A, она просто дает вам A, поэтому вызывается 2, так как он вызывается по неконстантному значению.

Если вычтобы вызвать 4, нужно сделать const A, и вы можете сделать это с помощью объявления псевдонима.Если у вас есть using A_const = const A;, то A_const{} дает вам const A и A_const{}.f() будет вызывать 4 вместо 2.

По сути, это static_assert(const A{}.f());, но поскольку синтаксически вы не можете писатьТаким образом, нам нужно использовать объявление, чтобы дать нам один тип слова, который является const A.


Кроме того, вы можете переписать

static_assert(A{}.f());

как

static_assert(std::add_const_t<A>{}.f());

, а также получите const A значение.

...