[英]Why does the following templated class member function not compile?
The following code compiles even though nonexisting_func()
doesn't exist.即使
nonexisting_func()
不存在,以下代码也会编译。 The code compiles because it's a member function of a templated class, but the function itself is not compiled because it's not being used in the program, correct?代码编译是因为它是模板化类的成员函数,但函数本身没有被编译,因为它没有在程序中使用,对吗? So you could have any syntax errors inside
heapify_down
and the entire code should still compile?所以你可能在
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;
}
If my understanding above is correct, then why does the following code not compile?如果我上面的理解是正确的,那么为什么下面的代码不能编译?
#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;
}
Compiling this code gives me the error error: use of undeclared identifier 'a'
.编译此代码给了我错误
error: use of undeclared identifier 'a'
。 Why is it trying to compile the heapify_down()
function now?为什么它现在试图编译
heapify_down()
函数?
Template code basically has two passes that it goes through.模板代码基本上有两遍。 The first pass just looks at the code and makes sure that it is syntactically correct, and that any non-dependent code is correct.
第一遍只是查看代码并确保它在语法上是正确的,并且任何非依赖代码都是正确的。 By non-dependent code, I mean code that does not depend on the template parameter(s).
非依赖代码是指不依赖于模板参数的代码。
After that there is a second pass that happens after the template is actually instantiated.之后,在实际实例化模板之后会发生第二次传递。 At that point there is no more dependent code as all the template parameters are known and the compiler can exam the code like it would for any non-template code.
那时没有更多的依赖代码,因为所有模板参数都是已知的,编译器可以像检查任何非模板代码一样检查代码。
In在
void heapify_down(std::vector<T> &vec)
{
nonexisting_func(vec);
}
The call to nonexisting_func
depends on vec
because of ADL and vec
depends on T
so it's compilation is deferred.要将呼叫
nonexisting_func
取决于vec
因为ADL和vec
取决于T
所以它的编译推迟。 It is syntactically correct so it wont have any further checking done until it is instantiated.它在语法上是正确的,因此在实例化之前不会进行任何进一步的检查。 If you changed main to
如果您将 main 更改为
int main( )
{
std::vector<int> foo;
heap<int> my_heap;
my_heap.heapify_down(foo);
return 0;
}
So that heapify_down
is actually instantiated then you would get a compiler error like所以
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.
You would also get an error using你也会得到一个错误使用
void heapify_down(std::vector<T> &vec)
{
::nonexisting_func(vec);
}
Because now we are no longer have an unqualified name so ADL is ignored meaning ::nonexisting_func
is no longer a dependent name.因为现在我们不再有一个不合格的名称,所以 ADL 被忽略,这意味着
::nonexisting_func
不再是一个依赖名称。
With和
void heapify_down(std::vector<T> &vec)
{
a;
nonexisting_func(vec);
}
a
doesn't depend on T
so the compiler tries to look it up. a
不依赖于T
因此编译器会尝试查找它。 It can't find it, so you get an error.它找不到它,所以你得到一个错误。 If you had instead done
如果你做了
void heapify_down(std::vector<T> &vec)
{
this->a;
nonexisting_func(vec);
}
then again you would not get an error until you instantiate the function since a
now depends on this
and this
depends on T
.然后再次在实例化函数之前不会出现错误,因为
a
now 取决于this
而this
取决于T
。
The key point here is that nonexisting_func(vec);
这里的关键点是
nonexisting_func(vec);
is going to mean something different depending on what T
is (since vec is a vector<T>
).将意味着不同的东西,具体取决于
T
是什么(因为 vec 是一个vector<T>
)。
So in that case, the compiler cannot try to resolve the call to nonexisting_func()
immediately as it lexes the function, and can only do so when comes the time to instantiate the template (which you never do).因此,在这种情况下,编译器无法在对函数进行词法分析时立即尝试解析对
nonexisting_func()
的调用,并且只能在实例化模板的时候这样做(您永远不会这样做)。
In the case of a
, since that identifier doesn't depend on anything, the compiler should perform the lookup immediately.在的情况下
a
,因为该标识符不依赖于任何东西,编译器应该立即进行查找。 I say should because MSVC in particular tends to still delay the lookup until instantiation, even though it shouldn't on paper.我说应该是因为 MSVC 特别倾向于将查找延迟到实例化,即使它不应该在纸上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.