【问题标题】:Template functions' order invoke a compilation error for no reason模板函数的顺序无缘无故调用编译错误
【发布时间】:2020-08-31 09:48:22
【问题描述】:

所以这很好用:

template<class V>
void bar(V v1, V v2) {
}

template <class T>
void foo(T t1, T t2) {
    bar(t1, t2);
}

int main() {
    foo(5, 6);
}

但是如果我像这样改变 foo 和 bar 的顺序:

template <class T>
void foo(T t1, T t2) {
    bar(t1, t2);
}

template<class V>
void bar(V v1, V v2) {
}

int main() {
    foo(5, 6);
}

我得到一个编译错误:

请参阅正在编译的函数模板实例化 'void foo(T,T)' 的参考

错误 C3861 'bar':找不到标识符 'bar':

'bar' 函数未在模板定义上下文中声明,可以 只能通过实例化中的参数相关查找找到 上下文

这是什么原因造成的?隐藏的问题是什么?这次我违反了什么cpp规则?
我会感谢您对此事的见解

编辑: 感谢您的 cmets,但由于某种原因将 bar 更改为 swap 会导致错误:
这段代码:

template<class V>
void swap(V v1, V v2) {
}

template <class T>
void foo(T t1, T t2) {
    swap(t1, t2);
}

int main() {
    foo(5, 6);
}

产生这个错误:

在尝试匹配参数列表 '(T, T)' 时,请参阅参考 函数模板实例化 'void foo(T,T)' 正在编译
或 'void std::swapstd::ios_base::iostate,0(_Ty &,_Ty &) noexcept' 可能是 'void swap(V,V)' 错误 C2668 'swap': 对重载函数的模糊调用

我知道 swap 不是 c++ 中的关键词。
是什么导致了这个错误?我已经在一个全新的项目中编写了这段代码,但它仍然无法正常工作

【问题讨论】:

  • 在 C++ 中,您必须始终在使用符号之前声明它们。在第二个示例中,当编译器看到对bar 的调用时,它不知道bar 是什么。函数是模板与这个问题无关。老实说,这应该在每本书、教程或课程中都有讲授。
  • 如果你真的想要它们按这个顺序,你可以加一个forward declaration
  • 如果它们不是模板,你就违反了同样的规则。
  • 我猜你的代码中有依赖循环,并且你已经减少了提供这个问题的问题(最好你尝试将问题减少到最低限度)。因此,我建议您提出新问题(在此处提供链接),它将介绍周期以及您需要它的原因。我们将在这个新问题中向您展示如何很好地打破这种依赖循环(它们对代码质量不利)。
  • 请看我的编辑

标签: c++ oop templates


【解决方案1】:

出于同样的原因,您会从这段代码中得到编译器错误:

void foo(T t1, T t2) {
    bar(t1, t2);
}

void bar(V v1, V v2) {
}

int main() {
    foo(5, 6);
}

您不能在声明之前调用bar。解决方案:要么在调用之前声明bar,要么将bar的整个定义移到foo之前。

【讨论】:

  • @forstackoverflowizi 新问题应该转到新问题。这是你老问题的答案。无论如何,问题是你不应该写你自己的swap,因为有std::swap,如果你仍然这样做你需要选择其中一个::swapstd::swap
  • 非常非常感谢!!!我简直不敢相信 std 命名空间会像那样弄乱我的代码。
猜你喜欢
  • 1970-01-01
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多