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

Antworten auf die Frage(6)

Ihre Antwort auf die Frage