在 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
不是成员函数模板的特化,所以上面不应该考虑。
考虑这个例子:
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
不是成员函数模板的特化,所以上面不应该考虑。