为什么我需要在 g++ 中使用 typedef typename 而不是 VS?

Why do I need to use typedef typename in g++ but not VS?(为什么我需要在 g++ 中使用 typedef typename 而不是 VS?)
本文介绍了为什么我需要在 g++ 中使用 typedef typename 而不是 VS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GCC 已经有一段时间没有抓住我了,但它就发生在今天.但我从来不明白为什么 GCC 需要在模板中使用 typedef typename,而 VS 和我猜想 ICC 不需要.typedef typename 是错误"还是过于严格的标准,还是留给编译器编写者的东西?

It had been a while since GCC caught me with this one, but it just happened today. But I've never understood why GCC requires typedef typename within templates, while VS and I guess ICC don't. Is the typedef typename thing a "bug" or an overstrict standard, or something that is left up to the compiler writers?

对于那些不明白我的意思的人,这里有一个示例:

For those who don't know what I mean here is a sample:

template<typename KEY, typename VALUE>
bool find(const std::map<KEY,VALUE>& container, const KEY& key)
{
    std::map<KEY,VALUE>::const_iterator iter = container.find(key);
    return iter!=container.end();
}

上面的代码在 VS 中编译(可能在 ICC 中),但在 GCC 中失败,因为它想要这样:

The above code compiles in VS (and probably in ICC), but fails in GCC because it wants it like this:

template<typename KEY, typename VALUE>
bool find(const std::map<KEY,VALUE>& container, const KEY& key)
{
    typedef typename std::map<KEY,VALUE>::const_iterator iterator; //typedef typename
    iterator iter = container.find(key);
    return iter!=container.end();
}

注意:这不是我正在使用的实际功能,而只是说明问题的一些愚蠢的东西.

Note: This is not an actual function I'm using, but just something silly that demonstrates the problem.

推荐答案

typename是标准要求的.模板编译需要两步验证.在第一次通过期间,编译器必须验证模板语法而不实际提供类型替换.在这一步中,std::map::iterator 被假定为一个值.如果它确实表示一个类型,则 typename 关键字是必需的.

The typename is required by the standard. Template compilation requires a two step verification. During the first pass the compiler must verify the template syntax without actually supplying the type substitutions. In this step, std::map::iterator is assumed to be a value. If it does denote a type, the typename keyword is required.

为什么这是必要的?在替换实际的 KEY 和 VALUE 类型之前,编译器不能保证模板不是特化的,并且特化不会将 iterator 关键字重新定义为其他内容.

Why is this necessary? Before substituing the actual KEY and VALUE types, the compiler cannot guarantee that the template is not specialized and that the specialization is not redefining the iterator keyword as something else.

您可以使用以下代码进行检查:

You can check it with this code:

class X {};
template <typename T>
struct Test
{
   typedef T value;
};
template <>
struct Test<X>
{
   static int value;
};
int Test<X>::value = 0;
template <typename T>
void f( T const & )
{
   Test<T>::value; // during first pass, Test<T>::value is interpreted as a value
}
int main()
{
  f( 5 );  // compilation error
  X x; f( x ); // compiles fine f: Test<T>::value is an integer
}

最后一次调用失败并出现错误,表明在 f() 的第一个模板编译步骤中,Test::value 被解释为一个值,但类型 X 的 Test<> 模板的实例化产生了一个类型.

The last call fails with an error indicating that during the first template compilation step of f() Test::value was interpreted as a value but instantiation of the Test<> template with the type X yields a type.

这篇关于为什么我需要在 g++ 中使用 typedef typename 而不是 VS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Rising edge interrupt triggering multiple times on STM32 Nucleo(在STM32 Nucleo上多次触发上升沿中断)
How to use va_list correctly in a sequence of wrapper functions calls?(如何在一系列包装函数调用中正确使用 va_list?)
OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping?(OpenGL透视投影裁剪多边形,顶点在视锥外=错误的纹理映射?)
How does one properly deserialize a byte array back into an object in C++?(如何正确地将字节数组反序列化回 C++ 中的对象?)
What free tiniest flash file system could you advice for embedded system?(您可以为嵌入式系统推荐什么免费的最小闪存文件系统?)
Volatile member variables vs. volatile object?(易失性成员变量与易失性对象?)