Я пытаюсь понять, что вижу, проверяя изменения. Платформа - openSUSE 42 с GCC 4.8, но это может повлиять на других. Затем следует тестовый код и ошибка.Почему я должен использовать const с constexpr для статической функции класса?
$ cat test.cxx
#include <string>
#if (__cplusplus >= 201103L)
# define STATIC_CONSTEXPR static constexpr
# define CONSTEXPR constexpr
#else
# define STATIC_CONSTEXPR static const
# define CONSTEXPR
#endif
struct Name
{
STATIC_CONSTEXPR char* GetName() {return "XXX";}
};
int main(int argc, char* arv[])
{
const char* name = Name::GetName();
return 0;
}
И:
$ g++ -O3 -std=c++11 test.cxx -o test.exe
test.cxx: In static member function ‘static constexpr char* Name::GetName()’:
test.cxx:13:44: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
STATIC_CONSTEXPR char* GetName() {return "XXX";}
^
Добавление следующих не ясно, что:
struct Name
{
STATIC_CONSTEXPR char* const GetName() {return "XXX";}
};
И добавив следующий делает ясно, что:
struct Name
{
STATIC_CONSTEXPR const char* GetName() {return "XXX";}
};
По Does static constexpr variable make sense?:
Каждая переменная объявлена constexpr неявно Const, но сопзЬ и статические почти ортогональны
Я думал, что я в основном (для взаимодействия со статическими константных чисел, за исключением.) понял constexpr
, но я, очевидно, что-то пропустил (снова). Насколько я понимаю, комитет C++ считает, что значение, подобное "XXX"
в проигрывателе, может как-то измениться после сохранения файла, даже если оно невозможно по законам физической вселенной, как мы их понимаем в настоящее время. Однако, чтобы бороться с проблемой, они дали нам constexpr
. Альтернативное объяснение - here, но я должен признать, что я не вижу более тонких деталей, которые делают разницу.
Почему я вижу предупреждение, и почему я действительно нуждаюсь в static constepr const
, чтобы раздавить его?
$ uname -a
Linux opensuse-42 4.1.27-27-default #1 SMP PREEMPT Fri Jul 15 12:46:41 UTC 2016 (84ae57e) x86_64 x86_64 x86_64 GNU/Linux
opensuse-42:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.8/lto-wrapper
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr ... --host=x86_64-suse-linux
Thread model: posix
gcc version 4.8.5 (SUSE Linux)
Нет, вы не понимаете проблему. «значение, подобное« XXX »в проигрывателе, может как-то измениться после сохранения файла» - это бессмысленное утверждение, которое не имеет к этому никакого отношения. Литеральная константа строки, «XXX» - это 'const char *', и ваш неудачный код пытается вернуть его как 'char *'. Указатель на постоянный объект не может быть преобразован в указатель на изменяемый объект, неявно. Это не имеет никакого отношения к 'constexpr'. –
Вы назначаете 'const char *', поэтому ваша функция должна возвращать 'const char *'. – Galik
Итак, я понятен ... Значение, возвращаемое из статической функции, помеченной как constexpr, не является неявным 'const'. Это верно? Это вызывает вопрос, если вместо функции function должно быть '... Name() {STATIC_CONSTEXPR char val [] =" XXX "; return val; } '? – jww