У меня есть расхождение между поведением g ++ 4.8.1 и clang ++ 3.4.Инициализация статического члена класса constexpr типа enum-класса с помощью явной функции преобразования
У меня есть класс A
, литерального типа, который имеет функцию преобразования explicit
constexpr
для ввода enum class E
.
Gcc позволяет мне инициализировать constexpr
переменные типа E
от постоянного выражения типа A
с использованием функции преобразования в некоторых случаях, но не тогда, когда переменная является членом статический класс (e2
ниже)
Clang отвергает инициализация во всех контекстах (e1
, e2
и e3
).
Согласно [over.match.conv]p1
использованию явной функции преобразования в порядке здесь
enum class E { e };
struct A { explicit constexpr operator const E() const noexcept { return E::e; } };
constexpr E e1{A{}}; // Gcc: OK, Clang: Error
struct B { static constexpr E e2{A{}}; }; // Gcc: Error, Clang: Error
void f() { static constexpr E e3{A{}}; } // Gcc: OK, Clang: Error
я вижу подобную картину при преобразовании в другой буквальный тип класса вместо перечислимого типа - г ++ отторгает инициализацию s1
, лязг отвергает инициализация s1
, s2
и s3
. Я думаю, что они также должны быть действительны, согласно [over.match.copy]p1
.
struct S { constexpr S(){} constexpr S(const S&){}};
struct A { explicit constexpr operator S() const noexcept { return S(); } };
constexpr S s1{A{}}; // Gcc: OK, Clang: Error
struct B { static constexpr S s2{A{}}; }; // Gcc: Error, Clang: Error
void f() { static constexpr S s3{A{}}; } // Gcc: OK, Clang: Error
Какой компилятор, если он есть, является правильным?
Edit: Несколько интересных вещей отметить:
- Результаты отличаются от лязга-3.4 и лязг-СВН см комментарии ниже.
- При использовании скобок для инициализации вместо скобок, по-прежнему существует разница между
e2
/s2
иe1
/e3
/s1
/s3
см http://coliru.stacked-crooked.com/a/daca396a63425c6b. gcc и clang-svn согласны, но я не уверен, что отклонение e2 и s2 является правильным.
отметить, что первые 3 примеры правильно компилировать на [Clang 3.5 SVN] (http://coliru.stacked-crooked.com/a/ dd5bbd2f90fe7457) – TemplateRex
@TemplateRex интересно, спасибо – je4d
также обратите внимание, что использование формы инициализации 'auto si = S (A {});' 'также работает для всех трех случаев: http://coliru.stacked-crooked.com/a/ 8f23cd452086ef40 Я не знаю, почему синтаксис 'S()' работает, когда 'S {}' не будет. – TemplateRex