Каков выводимый тип constexpr?

#c #c 11 #templates #overloading #constexpr

#c #c 11 #шаблоны #перегрузка #constexpr

Вопрос:

 #include <iostream>
#include <string>

void foo(intamp; k) { std::cout << "intamp;n"; }
void foo(intamp;amp; k) { std::cout << "intamp;amp;n"; }
void foo(const intamp; k) { std::cout << "const intamp;n"; }
void foo(const intamp;amp; k) { std::cout << "const intamp;amp;n"; }    
int main() {
  static  constexpr int k = 1;
  foo(k);
  foo(1);
}
  

Результат является:

 const intamp;
intamp;amp;
  

Как именно обрабатывается переменная constexpr?
Перегрузка для foo дает const intamp; .

Редактировать: Переходим к тому, что constexpr выводится как const Tamp; ;

Почему constexpr в области видимости класса не может быть передан функции, использующей универсальную ссылку?!

 #include <type_traits>

template <typename T>
void goo(Tamp;amp; k) {
  static_assert(std::is_same<decltype(k), const intamp;>::value, "k is const intamp;");
}

class F {
  static  constexpr int k = 1;
public:
  void kk2 () { goo(k); }
};

int main () {
  F a;
  a.kk2();
}
  

Вышеуказанное не удается скомпилировать, выдавая ошибку undefined reference to F::k
Однако приведенное ниже проходит:

 #include <type_traits>

template <typename T>
void goo(Tamp;amp; k) {
  static_assert(std::is_same<decltype(k), const intamp;>::value, "k is const intamp;");
}

int main() {
  static  constexpr int k = 1;
  goo(k);
}
  

Комментарии:

1. @GuillaumeRacicot Я думаю, что это предложение относится к goo(Tamp;amp; k) .

Ответ №1:

N3337 [dcl.constexpr]/9: constexpr Спецификатор, используемый в объявлении объекта, объявляет объект как const . […]

Поскольку вы объявили его k как constexpr , он также объявлен как const , поэтому const intamp; выбирается в разрешении перегрузки.

Ответ №2:

 foo(1);
  

В этом случае функции 1 передается временная переменная со значением foo , следовательно, неконстантное rvalue.

 /*static*/ constexpr int k = 1;
foo(k);
  

Здесь в функцию 1 передается именованная переменная const со значением foo , следовательно, const lvalue . static Ключевое слово не влияет на constexpr переменную в области видимости функции.

Как именно обрабатывается переменная constexpr?

При использовании в выражении, которое не является постоянным выражением, constexpr переменная является просто const переменной.

Почему constexpr в области видимости класса не может быть передан функции, использующей универсальную ссылку?!

Вы получаете ошибку компоновщика, потому что вы использовали переменную odr без ее определения. Вам нужно определение F::k в области пространства имен ровно в одной единице перевода, точно так же, как вы сделали для static const переменных-членов в C 98.