Visual C++编译器允许从属名称作为没有“typename”的类型吗?

发布于 2024-09-04 05:20:25 字数 456 浏览 14 评论 0原文

今天,我的一位朋友告诉我,下面的代码在他的 Visual Studio 2008 上编译得很好:

#include <vector>
struct A
{
  static int const const_iterator = 100;
};
int i;
template <typename T>
void PrintAll(const T & obj)
{
  T::const_iterator *i;
}
int main()
{
  std::vector<int> v;
  A a;
  PrintAll(a);
  PrintAll(v);
  return 0;
}

我通常使用 g++,它总是拒绝传递第二个 PrintAll() 调用。据我所知,对于这个问题,g++正在执行翻译模板的标准方法。

那么,到底是我的知识有误,还是VS2008的扩展呢?

Today one of my friends told me that the following code compiles well on his Visual Studio 2008:

#include <vector>
struct A
{
  static int const const_iterator = 100;
};
int i;
template <typename T>
void PrintAll(const T & obj)
{
  T::const_iterator *i;
}
int main()
{
  std::vector<int> v;
  A a;
  PrintAll(a);
  PrintAll(v);
  return 0;
}

I usually use g++, and it always refuse to pass the second PrintAll() call. As I know, for this problem, g++ is doing the standard way translating a template.

So, is my knowledge wrong, or is it a extension of VS2008?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉城メ夜风 2024-09-11 05:20:25

这根本不是扩展。

VC++ 从未正确实现两个阶段解释:

  1. 在定义时,解析模板并确定所有非依赖名称
  2. 在实例化时,检查模板是否生成有效代码

VC++ 从未实现第一阶段...这很不方便,因为这不仅意味着它接受不合规的代码,而且在某些情况下它会生成完全不同的代码。

void foo(int) { std::cout << "int" << std::endl; }

template <class T> void tfoo() { foo(2.0); }

void foo(double) { std::cout << "double" << std::endl; }

int main(int argc, char* argv[])
{
  tfoo<Dummy>();
}

使用此代码:

  • 兼容的编译器将打印“int”,因为它是模板定义时唯一可用的定义,并且 foo 的解析不依赖于 T
  • VC++ 将打印“double”,因为它从不关心阶段 1

就差异而言,这可能看起来很愚蠢,但是如果您考虑大型程序中包含的数量,则存在有人会引入重载的风险在你的模板代码之后...和 ​​BAM :/

This is not an extension at all.

VC++ never implemented the two phases interpretation properly:

  1. At the point of definition, parse the template and determine all non-dependent names
  2. At the point of instantiation, check that the template produces valid code

VC++ never implemented the first phase... it's inconvenient since it means not only that it accepts code that is non-compliant but also that it produces an altogether different code in some situations.

void foo(int) { std::cout << "int" << std::endl; }

template <class T> void tfoo() { foo(2.0); }

void foo(double) { std::cout << "double" << std::endl; }

int main(int argc, char* argv[])
{
  tfoo<Dummy>();
}

With this code:

  • compliant compilers will print "int", because it was the only definition available at the point of definition of the template and the resolution of foo does not depend on T.
  • VC++ will print "double", because it never bothered with phase 1

It might seem stupid as far as differences go, but if you think about the number of includes you have in a large program, there is a risk that someone will introduce an overload after your template code... and BAM :/

夜灵血窟げ 2024-09-11 05:20:25

我不确定“扩展”是否正是我在这方面描述 VC++ 的方式,但是,是的,gcc 在这方面具有更好的一致性。

I'm not sure "extension" is exactly how I'd describe VC++ in this respect, but yes, gcc has better conformance in this regard.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文