constexpr: литеральное поведение типа копирования класса

давайте возьмем следующий код:

class   const_int
{
public:
constexpr const_int(int data) : data_(data) {}
constexpr const_int(const const_int &) = default;
constexpr const_int(const_int &&) = default;

private:
int   data_;
};

class   test
{
public:

constexpr static const const_int      USER = 42;

constexpr static const double         NATIVE = 4.2;
};

// constexpr const const_int test::USER;

void    pass_by_copie(double)
{
}

void    pass_by_copie(const_int)
{
}

void    pass_by_const_ref(const const_int&)
{
}

void    pass_by_rvalue_ref(const_int&&)
{
}

int     main(void)
{

pass_by_copie(test::NATIVE);

pass_by_copie(test::USER);

pass_by_const_ref(test::USER);

pass_by_rvalue_ref(const_int(test::USER));

return (0);
}

Обе следующие строки:

pass_by_copie(test::USER);
pass_by_const_ref(test::USER);

выдать следующую ошибку под g++ 4.7 :

неопределенная ссылка на `test :: USER ‘

Я осознаю тот факт, что нет test::USER, (строка закомментирована специально)


У меня есть два вопроса:

  1. Почему явный случай test::USER необходимо, пока нет явного экземпляра test::NATIVE необходим для вызова функции pass_by_copie?

  2. Почему я могу позвонить pass_by_rvalue_ref по простоте создания временной копии из test::USER в то время как компилятор не может (или не хочет) неявно создавать тот же самый экземпляр при вызове pass_by_copie с test::USER ?

Спасибо

3

Решение

Clang 4.1 дает мне эту ошибку:

Undefined symbols for architecture x86_64:
"test::USER", referenced from:
_main in Untitled-gXrry2.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Я предполагаю, что здесь происходит test::NATIVE может быть просто заменено значением 4.2 где он используется, и на самом деле не требует символа. Но test::USERбудучи экземпляром класса, а не скаляра, требует символа, чтобы все ссылки на test::USER ссылаются на тот же объект. Учитывая это, вам действительно нужен явный экземпляр.

1

Другие решения

Из раздела 3.2 C ++ 11:

Переменная, имя которой появляется в качестве потенциально оцениваемого выражения: УСО используемый если это не объект, который удовлетворяет требованиям для появления в константном выражении, и преобразование lvalue-в-значение сразу применяется.

а также

Каждая программа должна содержать ровно одно определение каждой не встроенной функции или переменной, которая используется в этой программе

Таким образом, определение требуется, потому что test::USER используется odr, и, очевидно, он используется odr, потому что он не подвергается немедленному преобразованию lvalue в rvalue. Это удивляет меня, призыв к pass_by_copie похоже, что он выполняет преобразование lvalue в rvalue.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector