如何解决为什么在模板中我们可以使用从属名称而无需实例化而无需声明呢?
//void bar(int);
template <typename T>
void foo(T x)
{
bar(x);
}
void bar(int x)
{
std::cout << "bar(int)\n";
}
template <int>
void foo(int i)
{
bar(i);
}
int main()
{
foo<int>(4);
std::cout << "\ndone!\n";
}
我故意注释了函数bar(int)
的声明。此功能bar(int)
在模板功能dependent name
中用作foo
。因此它受实例约束。
- 我已经在
bar
之后和foo
专业化之前定义了foo<int>
,以便后者可以看到bar(int)
。
‘bar’ was not declared in this scope,and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]|
。如果我取消对bar(int)
声明的注释,它可以正常工作吗?!
-
如果在使用模板作为依赖名称之前必须先声明一个名称,那么为什么C ++允许实例化(如果不实例化)。 (如果我不“使用”模板化函数
foo
,则该代码有效)?template <typename U> void do_it(U u) { print(u); // not bound until instantiation }
那么允许在尚未声明的print(u)
中调用do_it
并在实例化时失败的背后的想法是什么?
解决方法
在您的程序中,此定义:
template <int> // not a specialization,just a different
void foo(int i) // template with a non-type template parameter
{
bar(i);
}
实际上并未定义foo
主模板的专业化。因此,当您拨打电话时:
Foo<int>(4);
您最终调用了主模板。查找名称bar
找不到该名称,您会收到错误消息。
如果相反,您实际上像这样为foo
编写了int
的专业化内容:
template <> // specialization of primary
void foo<int>(int i) // template foo with int
{
bar(i);
}
然后调用foo<int>(4);
就可以了,因为它调用了特殊化,并且此时查找bar
确实找到了该名称。
现在回到您的程序(不进行专业化处理),如果从未实例化foo
会发生什么,例如,因为没有调用?好的,程序仍然是错误的,但是编译器可能不会告诉您。这是您使用print
和do_it
描述的行为,这被正式称为病态,不需要诊断。
请注意该错误输出中的行号。
您正在实例化第一个模板。第二个模板不是第一个模板的规范,而是一个功能模板,该模板需要一个未使用的int
模板参数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。