I am struggling with making C++11 code Clang compatible and ran into a case where GCC >= 4.6 accepts code and Clang >= 3.1 doesn't. Clang deems a candidate constructor not viable
.
Here is a trimmed down example to illustrate the issue:
#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;
}
The error I get is:
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.
I do not understand why clang complains about the lack of a conversion possibility, because I think this "catch-all" constructor should work:
template <typename Arg0, typename... Args>
void_type(Arg0&&, Args&&...) { }
So the error I am confused about is:
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)) { }
^
After all, GCC accepts the code. Is this perhaps a Clang bug? (I am using the latest Clang from the LLVM git repository.)
Indeed, this was a Clang bug. It turned out that variadic constructors are mistakenly marked as explicit. Fixed in Clang r158040.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With