2012-05-31 35 views
10

梗概

我正在与制备C++ 11代码锵兼容挣扎跑进其中GCC> = 4.6接受代码和锵> = 3.1的情况下则没有。铿锵认为candidate constructor not viable锵问题:在构造时隐式类型转换

详细

下面是一个下调的例子来说明这个问题:

#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; 
} 

我得到的错误是:

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. 

我不明白为什么铛抱怨缺乏的转换可能性,因为我认为这个“通吃”的构造函数应该工作:

template <typename Arg0, typename... Args> 
void_type(Arg0&&, Args&&...) { } 

所以我很困惑的错误是:

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)) { } 
    ^

毕竟,GCC接受的代码。这可能是一个诅咒错误? (我正在使用LLVM git仓库中的最新Clang。)

+0

@dirkgently:然而,即使使用这个名字,你也应该能够提供帮助。毕竟你是找到薛定谔猫的侦探。 – LiKao

+1

如果您尝试从原子直接创建void_type,会发生什么情况:'void_type v(a)'? –

+0

@DaveS:这个编译就好了。它给你一个线索为什么构造函数中的隐式转换失败? – mavam

回答

1

事实上,这是一个叮当bug。事实证明,可变参数构造函数被错误地标记为明确的。 Fixed in Clang r158040