передать статическую переменную constexpr по универсальной ссылке?
В следующих,static constexpr
членL
инициализируется в классеA
и затем передается по значению или (универсальная) ссылка. Последний сбой в Clang, но не в GCC, и поведение немного отличается для функций-членов / не-членов. Более подробно:
#include <iostream>
using namespace std;
struct A
{
static constexpr size_t L = 4;
template <typename T>
void member_ref(T&& x) { cout << std::forward<T>(x) << endl; }
template <typename T>
void member_val(T x) { cout << x << endl; }
};
template <typename T>
void ref(T&& x) { cout << std::forward<T>(x) << endl; }
template <typename T>
void val(T x) { cout << x << endl; }
int main ()
{
A().member_ref(A::L); // Clang: linker error: undefined reference to `A::L'
A().member_val(A::L); // fine (prints 4)
ref(A::L); // Clang: compiles/links fine, no output
val(A::L); // fine (prints 4)
}
После некоторых экспериментов по выделению проблемы из более крупной программы я понял, что случайно использую адресconstexpr
переменная, хотя меня интересует только значение.
Я хочу передать (универсальную) ссылку, чтобы код был универсальным и работал с большими структурами без копирования. Я думал, что вы могли бы передать что-нибудь с универсальной ссылкой, но, похоже, это не тот случай. Я не могу использовать отдельное (внеклассное) определение дляL
потому что это часть библиотеки только для заголовка.
Таким образом, одним из обходных путей может быть создание значения по вызову, то есть, скажем,size_t(A::L)
или что-то вродеA::get_L()
вместо простоA::L
где (внутри классаA
)
static constexpr size_t get_L() { return L; }
но оба решения выглядят немного неуклюже. В моем реальном коде вызов сделан внутри класса и выглядит какcall(0, L, ...)
что выглядит довольно невинно (0, L
выглядят как ценности). Я хотел бы сделать звонок максимально простым.
Я думаюэтот вопрос а такжеего продолжение в значительной степени объяснить, что происходит. Так кто-нибудь может предложить, какой будет самый чистый способ справиться с этим?