繁体   English   中英

为什么以下模板化类成员函数无法编译?

[英]Why does the following templated class member function not compile?

即使nonexisting_func()不存在,以下代码也会编译。 代码编译是因为它是模板化类的成员函数,但函数本身没有被编译,因为它没有在程序中使用,对吗? 所以你可能在heapify_down有任何语法错误并且整个代码仍然应该编译?

#include <iostream>
#include <vector>

template<typename T>
class heap
{
public:
   void heapify_down(std::vector<T> &vec)
   {
      nonexisting_func(vec);
   }
};

int main( ) 
{ 
   heap<int> my_heap;
   return 0;
}

如果我上面的理解是正确的,那么为什么下面的代码不能编译?

#include <iostream>
#include <vector>

template<typename T>
class heap
{
public:
   void heapify_down(std::vector<T> &vec)
   {
      a;
      nonexisting_func(vec);
   }
};

int main( ) 
{ 
   heap<int> my_heap;
   return 0;
}

编译此代码给了我错误error: use of undeclared identifier 'a' 为什么它现在试图编译heapify_down()函数?

模板代码基本上有两遍。 第一遍只是查看代码并确保它在语法上是正确的,并且任何非依赖代码都是正确的。 非依赖代码是指不依赖于模板参数的代码。

之后,在实际实例化模板之后会发生第二次传递。 那时没有更多的依赖代码,因为所有模板参数都是已知的,编译器可以像检查任何非模板代码一样检查代码。

void heapify_down(std::vector<T> &vec)
{
    nonexisting_func(vec);
}

要将呼叫nonexisting_func取决于vec因为ADLvec取决于T所以它的编译推迟。 它在语法上是正确的,因此在实例化之前不会进行任何进一步的检查。 如果您将 main 更改为

int main( ) 
{ 
   std::vector<int> foo;
   heap<int> my_heap;
   my_heap.heapify_down(foo);
   return 0;
}

所以heapify_down实际上是实例化的,那么你会得到一个编译器错误,比如

main.cpp:22:7: error: use of undeclared identifier 'nonexisting_func'
      nonexisting_func(vec);
      ^
main.cpp:30:12: note: in instantiation of member function 'heap<int>::heapify_down' requested here
   my_heap.heapify_down(foo);
           ^
1 error generated.

你也会得到一个错误使用

void heapify_down(std::vector<T> &vec)
{
    ::nonexisting_func(vec);
}

因为现在我们不再有一个不合格的名称,所以 ADL 被忽略,这意味着::nonexisting_func不再是一个依赖名称。

void heapify_down(std::vector<T> &vec)
{
   a;
   nonexisting_func(vec);
}

a不依赖于T因此编译器会尝试查找它。 它找不到它,所以你得到一个错误。 如果你做了

void heapify_down(std::vector<T> &vec)
{
   this->a;
   nonexisting_func(vec);
}

然后再次在实例化函数之前不会出现错误,因为a now 取决于thisthis取决于T

这里的关键点是nonexisting_func(vec); 将意味着不同的东西,具体取决于T是什么(因为 vec 是一个vector<T> )。

因此,在这种情况下,编译器无法在对函数进行词法分析时立即尝试解析对nonexisting_func()的调用,并且只能在实例化模板的时候这样做(您永远不会这样做)。

在的情况下a ,因为该标识符不依赖于任何东西,编译器应该立即进行查找。 我说应该是因为 MSVC 特别倾向于将查找延迟到实例化,即使它不应该在纸上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM