使用函数模板进行函数重载

Using function templates for function overloading

提问人:lu4nik 提问时间:4/10/2023 最后编辑:lu4nik 更新时间:4/10/2023 访问量:42

问:

我试图在遵守 DRY 原则的同时重载函数。重载之间的唯一区别是参数类型,因此我选择使用模板。我基本上想出了以下代码:

a.h:

#ifndef A_H
#define A_H
    
#include <vector>
    
template<typename T>
void func(std::vector<T>& vec);
    
void func(std::vector<double>& vec) { func<double>(vec); }
    
void func(std::vector<int>& vec) { func<int>(vec); }
    
void otherfunc();
    
#endif // A_H

a.cc:

#include "a.h"
    
template<typename T>
void func(std::vector<T>& vec)
{
  vec.resize(10);
}
    
void otherfunc()
{
  std::vector<double> x;
  func(x);
}
    
template void func<double>(std::vector<double>&);
template void func<int>(std::vector<int>&);

main.cc:

#include "a.h"
    
int main()
{
  otherfunc();
  return 0;
}

此代码产生链接错误:

/nix/store/y5jcw4ymq7qi735wbm7va9yw3nj2qpb9-binutils-2.39/bin/ld: /run/user/1000/cc6xxYLN.o: in function `func(std::vector<double, std::allocator<double> >&)':
main.cc:(.text+0x0): multiple definition of `func(std::vector<double, std::allocator<double> >&)'; /run/user/1000/ccUyR0Cy.o:a.cc:(.text+0x0): first defined here
/nix/store/y5jcw4ymq7qi735wbm7va9yw3nj2qpb9-binutils-2.39/bin/ld: /run/user/1000/cc6xxYLN.o: in function `func(std::vector<int, std::allocator<int> >&)':
main.cc:(.text+0x10): multiple definition of `func(std::vector<int, std::allocator<int> >&)'; /run/user/1000/ccUyR0Cy.o:a.cc:(.text+0x80): first defined here
collect2: error: ld returned 1 exit status

令人惊讶的是,在不使用显式实例化时,会出现奇怪的链接错误:

/nix/store/y5jcw4ymq7qi735wbm7va9yw3nj2qpb9-binutils-2.39/bin/ld: /run/user/1000/ccpXFxFV.o: in function `func(std::vector<double, std::allocator<double> >&)':
main.cc:(.text+0x0): multiple definition of `func(std::vector<double, std::allocator<double> >&)'; /run/user/1000/ccMYxyNR.o:a.cc:(.text+0x0): first defined here
/nix/store/y5jcw4ymq7qi735wbm7va9yw3nj2qpb9-binutils-2.39/bin/ld: /run/user/1000/ccpXFxFV.o: in function `func(std::vector<int, std::allocator<int> >&)':
main.cc:(.text+0x10): multiple definition of `func(std::vector<int, std::allocator<int> >&)'; /run/user/1000/ccMYxyNR.o:a.cc:(.text+0xc0): first defined here
/nix/store/y5jcw4ymq7qi735wbm7va9yw3nj2qpb9-binutils-2.39/bin/ld: /run/user/1000/ccpXFxFV.o: in function `func(std::vector<double, std::allocator<double> >&)':
main.cc:(.text+0x1): undefined reference to `void func<double>(std::vector<double, std::allocator<double> >&)'
/nix/store/y5jcw4ymq7qi735wbm7va9yw3nj2qpb9-binutils-2.39/bin/ld: /run/user/1000/ccpXFxFV.o: in function `func(std::vector<int, std::allocator<int> >&)':
main.cc:(.text+0x11): undefined reference to `void func<int>(std::vector<int, std::allocator<int> >&)'
collect2: error: ld returned 1 exit status

为什么会出现这些错误?如何修复代码?

我正在使用带有标志的 GCC 11.3.0。-Wall -Wextra -std=c++17

C++ 重载 function-templates explicit-instantiation

评论

0赞 NathanOliver 4/10/2023
尝试使用代替::func<double>(vec);func<double>(vec);
3赞 Drew Dormann 4/10/2023
错字? 你想期待一个?template void func<int>(std::vector<double>&);func<int>std::vector<double>
0赞 lu4nik 4/10/2023
@DrewDormann没错,我在编写和检查代码时完全错过了它,将更新问题。
0赞 lu4nik 4/10/2023
@NathanOliver它仍然会产生相同的错误。您能解释一下这里有什么帮助吗?我以为函数声明已经在顶级命名空间中。::
2赞 Eljay 4/10/2023
在 中,有两个函数声明定义,但它们没有被标记。这是疏忽吗?a.hinline

答:

0赞 lu4nik 4/10/2023 #1

我错过了 和 函数的说明符,因为它们的定义在头文件中。感谢 @DrewDormann 和 @Eljay!inlinevoid func(std::vector<double>&)void func(std::vector<int>&)