Synopsis
ich mit der Herstellung C++ 11-Code Clang kompatibel bin zu kämpfen und lief in einen Fall, in dem GCC> = 4.6 akzeptiert Code und Clang> = 3,1 nicht. Clang hält eine candidate constructor not viable
.Clang Ausgabe: implizite Typumwandlung bei Bauzeiten
Einzelheiten
Hier ist ein Beispiel, das Problem zu veranschaulichen abgespeckte:
#include <utility>
template <typename...>
struct T;
template<>
struct T<>
{
typedef T super;
constexpr T() { }
template <typename... Args>
T(Args&&...) { }
};
template <typename Head, typename... Tail>
struct T<Head, Tail...> : T<Tail...>
{
typedef T<Tail...> super;
Head head;
T(Head arg) : super(), head(std::move(arg)) { }
};
struct void_type
{
constexpr void_type() { }
constexpr void_type(const void_type&) { }
void_type& operator=(const void_type&) = default;
template <typename Arg0, typename... Args>
void_type(Arg0&&, Args&&...) { }
};
struct atom { };
int main()
{
atom a;
T<void_type> t(a);
return 0;
}
Der Fehler, den ich bekommen ist:
ctor-init.cpp:44:18: error: no matching constructor for initialization of 'T<void_type>'
T<void_type> t(a);
^~
ctor-init.cpp:19:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'atom' to 'const T<void_type>' for 1st argument;
struct T<Head, Tail...> : T<Tail...>
^
ctor-init.cpp:25:5: note: candidate constructor not viable: no known conversion from 'atom' to 'void_type' for 1st argument;
T(Head arg) : super(), head(std::move(arg)) { }
^
1 error generated.
Ich verstehe nicht, warum über den Mangel Klirren beklagt einer Konvertierungsmöglichkeit, weil ich denke, dass dieser "Catch-All" -Konstruktor funktionieren sollte:
template <typename Arg0, typename... Args>
void_type(Arg0&&, Args&&...) { }
So ist der Fehler, den ich bin verwirrt über ist:
ctor-init.cpp:25:5: note: candidate constructor not viable: no known conversion from 'atom' to 'void_type' for 1st argument;
T(Head arg) : super(), head(std::move(arg)) { }
^
Immerhin GCC den Code akzeptiert. Ist das vielleicht ein Clang Bug? (Ich verwende den neuesten Clang aus dem LLVM Git Repository.)
@dirkgently: Mit diesem Namen sollten Sie jedoch auch mit diesem abgespeckten Beispiel helfen können. Schließlich bist du der Detektiv, der Schrödingers Cat gefunden hat. – LiKao
Was passiert, wenn Sie versuchen, einen void_type direkt vom Atom zu erzeugen: 'void_type v (a)'? –
@DaveS: das kompiliert einfach gut. Gibt es einen Hinweis darauf, warum die implizite Konvertierung im Konstruktor fehlschlägt? – mavam