#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.