在 VC++2008 Express 中查找不依赖于模板参数的名称。它是一个错误吗?
Posted
技术标签:
【中文标题】在 VC++2008 Express 中查找不依赖于模板参数的名称。它是一个错误吗?【英文标题】:Name lookup for names not dependent on template parameter in VC++2008 Express. Is it a bug? 【发布时间】:2010-05-05 16:24:59 【问题描述】:在尝试使用 C++ 模板时,我设法生成了这个简单的代码,其输出不同于我对 C++ 规则的理解所期望的。
void bar(double d)
std::cout << "bar(double) function called" << std::endl;
template <typename T> void foo(T t)
bar(3);
void bar(int i)
std::cout << "bar(int) function called" << std::endl;
int main()
foo(3);
return 0;
当我在 VC++2008 Express 中编译这段代码时,函数 bar(int)
被调用。这将是行为,我希望模板正文中的bar(3);
依赖于模板参数。但事实并非如此。我发现here 的规则说“C++ 标准规定,在解析模板函数或类时,所有不依赖于模板参数的名称都绑定到它们当前的定义”。我错了吗,解析模板函数foo
时bar
的“当前定义”是
void bar(double d);
?如果我错了,为什么不是这样。此编译单元中没有bar
的前向声明。
【问题讨论】:
如果你是对的,我不会感到惊讶。在我看来,VC++ 的模板实现完全忽略了依赖/非依赖问题。 VC++ 从不遵守标准的 2-passes 评估(第一次在读取模板定义时,第二次在模板实例化时)。它在某些地方节省了typename
和 template
的写法,但是……不合规。
为了精确起见,您指的是标准的第 14.6.3 节非依赖名称 [temp.nondep]。 (最终草案)
【参考方案1】:
这确实是编译器中的一个错误。已知该问题存在于 VS2005 和之前的版本中(我使用 Blogspot 博客作为此类案例的笔记本,请参阅 1.3 here)。显然它也存在于 VS2008 中。
你可以用下面的简单代码测试一下
int bar(double d) return 0;
template <typename T> void foo(T t)
int i = bar(3);
void bar(int i);
int main()
foo(3);
这段代码格式正确(您可以使用 Comeau Online 编译器对其进行编译),但我敢打赌 VS 会卡住它,因为在这种情况下 VS 错误地实现了两阶段查找。
【讨论】:
是的,VS(至少是我的 Express 版本,但我认为它与其他编译器相同)声称代码中有错误。谢谢。【参考方案2】:AndreyT 是正确的。事实上,您的代码实际上与标准(§14.6.3/1)中的示例相同:
void g(double);
void h();
template<class T> class Z
public:
void f()
g(1); //calls g(double)
h++; //ill-formed: cannot increment function;
// this could be diagnosed either here or
// at the point of instantiation
;
void g(int); // not in scope at the point of the template
// definition, not considered for the call g(1)
【讨论】:
以上是关于在 VC++2008 Express 中查找不依赖于模板参数的名称。它是一个错误吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 VC++ 2008 Express 进行 ATL 开发
无法安装 SQL Server 2008 R2 Express
Visual C++ 2008 Express 中的代码定义窗口是啥?