为什么 VC++2013 在用作模板函数返回类型时拒绝编译嵌套类型,使用 using 关键字使其可见?

Why does VC++2013 refuse to compile nested types, made visibile with the using keyword, when used as a template functions return type?

提问人:neurotempest 提问时间:8/28/2014 最后编辑:JasonMArcherneurotempest 更新时间:6/7/2015 访问量:191

问:

Visual Studio 2013 (update 2) 在编译模板函数时引发编译时错误,该函数的返回类型是嵌套类型名称,该名称已通过多重继承隐藏,并使用关键字再次可见;如以下代码所示:using

struct Base1
{
  typedef int value_type;
};

struct Base2
{
  typedef double value_type;
};

struct Derived : Base1, Base2
{
  using Base1::value_type;
};

template<typename T>
typename T::value_type nullary_function() { return 0; }

template<typename T>
typename T::value_type unary_function(T t) { return 0; }

int main()
{
  nullary_function<Derived>(); // Error: C2770
  unary_function( Derived() ); // Error: C2893
  return 0;
}

(错误号因函数是否接受模板参数而异,如注释中所示。

G++ 4.7 接受此代码。

具体来说,我想知道 C++ 标准对此事有什么看法,以及这是否是 VC++ 编译器错误。(在我看来,据我所知,使用关键字使嵌套类型可见使它们在所有其他情况下都可见。using

我还知道带有关键字的行可能会从using

using Base1::value_type;

typedef Base1::value_type value_type;

为了让代码正确编译和运行,但对于某些(潜在)有效的代码来说,在某些编译器上编译而不是在其他编译器上编译似乎不利 - 因此需要澄清。

C++ 模板 visual-studio-2013 嵌套 多重继承

评论

0赞 Mike Seymour 8/28/2014
“这似乎不利于可移植性”——愤世嫉俗的人可能会指出,为他们的平台编写的代码不具有可移植性可能符合平台供应商的利益。但我敢肯定,这个编译器对语言的特殊解释是有完全无辜的。
0赞 Zoomulator 8/28/2014
根据我的经验,最新的更新完全被打破了。以前有效的模板推导现在使编译器崩溃!
1赞 Antoine 8/28/2014
在你不需要,因为不依赖typedef typename Base1::value_type value_type;typenameBase1
3赞 neurotempest 8/28/2014
@Niall - 是的,我打算为它提交一个错误;只是想得到一些确认,我首先不是白痴,因为大多数编译器错误都不是!:)
1赞 neurotempest 9/10/2014
这已作为错误提交;错误报告在这里

答:

0赞 LThode 11/13/2014 #1

这确实是一个编译器错误——ICC、CLang 和 G++ 都接受此代码作为在 Godbolt 上验证的代码。

我能找到的标准中最适用的语言是 7.3.3 (namespace.udecl) p2(引自 N3337)

每个 using-declaration 都是一个声明和一个成员声明,因此可以使用 在类定义中。

P.S. ICC、CLang 和 G++ 也都接受 typedef 版本。