在“思考在c++”写的澄清和总结:如果名称是依赖的,则在示例化时进行名称查找,除了对于不合格的依赖名称,在定义时也早期尝试正常的名称查找。早期尝试的非限定依赖名称的确切示例是什么?我不知道为什么会有这个例外。先谢谢你了。举例说明。
sg2wtvxw1#
下面是一个例子:
void f(int);template<typename T>void g(T x) { f(x); // Lookup of f here finds f(int)}void f(double);struct S {};void f(S);int main() { g(0); // Calls f(int) found through early lookup g(0.0); // Still calls f(int) since f(double) can't be found via ADL g(S()); // Calls f(S) found via ADL}
void f(int);
template<typename T>
void g(T x) {
f(x); // Lookup of f here finds f(int)
}
void f(double);
struct S {};
void f(S);
int main() {
g(0); // Calls f(int) found through early lookup
g(0.0); // Still calls f(int) since f(double) can't be found via ADL
g(S()); // Calls f(S) found via ADL
当调用f(x)时,候选函数是通过“正常”查找+在通过ADL关联的所有命名空间的作用域中查找找到的名称。正常的查找可以被认为是语义上发生在函数模板的声明中,而不是任何特定的专门化(g<int>,g<double>或g<S>)示例化。
f(x)
g<int>
g<double>
g<S>
ylamdve62#
带有依赖函数参数的非限定查找考虑:
我认为这句话是想说,候选函数的列表可能在定义时构建(前半部分),然后在示例化期间的查找之前增加(后半部分)。
fgw7neuy3#
请考虑以下示例:
template <typename T>struct foo_unqualified : T { foo_unqualified() { b<T>(); }};
template <typename T>
struct foo_unqualified : T {
foo_unqualified() {
b<T>();
};
没有b,因此有error:
b
<source>:5:9: error: there are no arguments to 'b' that depend on a template parameter, so a declaration of 'b' must be available [-fpermissive] 5 | b<T>(); | ^~~~
<source>:5:9: error: there are no arguments to 'b' that depend on a template parameter, so a declaration of 'b' must be available [-fpermissive]
5 | b<T>();
| ^~~~
现在考虑这个例子:
template <typename T>struct foo_qualified : T { foo_qualified() { foo_qualified::template b<T>(); }};
struct foo_qualified : T {
foo_qualified() {
foo_qualified::template b<T>();
这里还没有定义foo_qualified::b,这就是为什么这里的编译器需要关键字typename。只有在示例化时,才会真正查找名称:
foo_qualified::b
typename
struct bar { template <typename T> void b(){}};struct no_bar {};int main() { foo_qualified<bar> f; foo_qualified<no_bar> f2; // error}
struct bar {
void b(){}
struct no_bar {};
foo_qualified<bar> f;
foo_qualified<no_bar> f2; // error
foo_qualified<bar>的示例化很好。foo_qualified<bar>继承自bar,现在有一个foo_qualified<bar>::b()模板。foo_qualified<no_bar>失败,因为查找失败(现在仅在示例化时)。Live Demo
foo_qualified<bar>
bar
foo_qualified<bar>::b()
foo_qualified<no_bar>
3条答案
按热度按时间sg2wtvxw1#
下面是一个例子:
当调用
f(x)
时,候选函数是通过“正常”查找+在通过ADL关联的所有命名空间的作用域中查找找到的名称。正常的查找可以被认为是语义上发生在函数模板的声明中,而不是任何特定的专门化(g<int>
,g<double>
或g<S>
)示例化。ylamdve62#
带有依赖函数参数的非限定查找考虑:
我认为这句话是想说,候选函数的列表可能在定义时构建(前半部分),然后在示例化期间的查找之前增加(后半部分)。
fgw7neuy3#
请考虑以下示例:
没有
b
,因此有error:现在考虑这个例子:
这里还没有定义
foo_qualified::b
,这就是为什么这里的编译器需要关键字typename
。只有在示例化时,才会真正查找名称:
foo_qualified<bar>
的示例化很好。foo_qualified<bar>
继承自bar
,现在有一个foo_qualified<bar>::b()
模板。foo_qualified<no_bar>
失败,因为查找失败(现在仅在示例化时)。Live Demo