C++可变参数模板和隐式转换

Lag*_*agf 6 c++ templates implicit-conversion variadic-templates

我想弄清楚当存在可变参数模板构造函数和转换运算符时,C++编译器如何解析隐式转换.这是一个最小的例子来说明:

我写的时候:

#include <iostream>

class A {
public:
    A () {}

    template<typename...tTypes> A (tTypes...pArgs) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

class B {
public:
    operator A () const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        return A();
    }
};

int main() {
    B b;
    A a = b;
}
Run Code Online (Sandbox Code Playgroud)

在运行时,我得到这个输出:B::operator A() const.所以它正在使用转换运算符(正如我所料).http://ideone.com/ZZ2uBz上的实例

但是,当A模板结果不同时:

#include <iostream>

template<typename tType>
class A {
public:
    A () {}

    template<typename...tTypes> A (tTypes...pArgs) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

class B {
public:
    template<typename tType>
    operator A<tType> () const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        return A<tType>();
    }
};

int main() {
    B b;
    A<float> a = b;
}
Run Code Online (Sandbox Code Playgroud)

运行这个程序时,我得到了这个输出:A<tType>::A(tTypes ...) [with tTypes = {B}; tType = float].所以它使用的是变量构造函数A而不是转换运算符B.http://ideone.com/u9Rxuh上的实例

有人可以向我解释为什么会有区别吗?转换运算符不应该优先于构造函数吗?

我知道我可以显式调用转换运算符(A<float> a = b.operator A<float>();)但这不是我想要的.

sky*_*ack 2

在我看来,转换是不明确的,其他编译器按预期失败(或者至少,这是我的预期)。请参阅使用clang的结果示例。

要消除歧义,您可以显式构造函数或转换运算符。
例如,使用这个:

template<typename tType>
class A {
public:
    A () {}

    template<typename...tTypes> explicit A (tTypes...pArgs) { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)

或这个:

class B {
public:
    template<typename tType>
    explicit operator A<tType> () const { return A<tType>(); }
};
Run Code Online (Sandbox Code Playgroud)