在 T 是模板类型参数的情况下是否允许使用 Base::operator T?

Is `using Base::operator T` allowed where `T` is a template type parameter?

考虑这个例子:

struct B { operator int(); };

template<class T>
struct X:B
{
    using B::operator T;
};

GCC accepts the code, while Clang 并且 MSVC 拒绝了它。 哪个是正确的?

请注意,如果基类型是依赖的,则所有编译器都接受代码:

template<class T>
struct B { operator T(); };

template<class T>
struct X:B<T>
{
    using B<T>::operator T;
};

嗯... Gcc 也不喜欢第一个。除非您尝试使用 int 以外的模板参数创建 struct X 的实例,否则它会编译。 X<double>::operator double() 是什么意思? Class B 没有这样的运算符,但我们会尝试使用它。

总结一下:MSVC 和 clang 会尝试事先警告您(即使您现在没有做任何非常愚蠢的事情),而 gcc 只有在您尝试创建不正确的东西时才会产生错误。这不会在 gcc (5.3.0) 中编译:

#include <iostream>

struct B { operator int(); };

template<class T>
struct X:B
{
    using B::operator T;
};

int main(int argc, char **argv)
{
    X<char> x;
    std::cout << "Hello!" << std::endl;
    return 0;
}

我认为GCC是对的,在§7.3.3/1中,我们可以发现:

The set of declarations introduced by the using-declaration is found by performing qualified name lookup (3.4.3, 10.2) for the name in the using-declaration, excluding functions that are hidden as described below.

我看不出有什么理由找不到 operator T,实际上:

template<class T>
struct X: B {
    T f () { return B::operator T; }
};

...使用 g++ 和 clang 编译良好(未在 MSVC 上测试)。

我在标准中找不到任何特定于用于限定名称查找的转换函数的内容,除了:

Since specializations of member templates for conversion functions are not found by name lookup, they are not considered when a using-declaration specifies a conversion function (14.5.2).

但是B::operator int不是成员函数模板的特化,所以上面不应该考虑。