Type-Konvertierung bei nicht typisiertem Template-Argument ohne constexpr
Betrachten Sie den folgenden Code:
struct A {
constexpr operator int() { return 42; }
};
template <int>
void foo() {}
void bar(A a) {
foo<a>();
}
int main() {
foo<A{}>();
const int i = 42;
foo<i>(); // (1)
A a{};
static_assert(i == a, "");
bar(a);
foo<a>(); // error here
}
Clang 3.7 mit c ++ 14 akzeptiert dies, während gcc 5.2.0 mit c ++ 14 dies nicht tut und die folgende Meldung erzeugt:
/tmp/gcc-explorer-compiler1151027-68-1f801jf/example.cpp: In function 'int main()':
26 : error: the value of 'a' is not usable in a constant expression
foo<a>();
^
23 : note: 'a' was not declared 'constexpr'
A a{};
^
Compilation failed
Änderna
seinconstexpr
wie von gcc vorgeschlagen behebt den gcc-Kompilierungsfehler, aber ohneconstexpr
, welcher Compiler ist richtig?
Für mich scheint es, dassa
sollte "in konstantem Ausdruck verwendbar" sein, alsstatic_assert
bestätigt. Darüber hinaus ist die Tatsache, dassi
kann auf die gleiche Weise verwendet werden (markiert mit(1)
) und die Tatsache, dassbar()
kompiliert, lässt mich auch denken, dass gcc falsch ist.
UPD: hat einen Fehler gegen gcc gemeldet:https: //gcc.gnu.org/bugzilla/show_bug.cgi? id = 68588