重载时区分函数

Differentiate functions when overloading

本文关键字:函数 时区 重载      更新时间:2023-10-16

我正在编写两个同名(参数相似)的函数:第一个仅采用可变数量的整数参数(最小一个)。第二个采用可变量的struct coordinate作为参数(同样是最小值)。struct coordinate可以由intstd::vector<int>构成,因此第二个也可以采用intstd::vector<int>。问题是,如果第二个函数的第一个参数是int,则编译失败。是否可以使main()中的第三行调用另一个tmp函数?下面列出了我当前的实现方式。

int main(int argc, char** argv)
{
    tmp(1, 2, 3, 4, 5);                   // OK! First function calls 'single'
    tmp(std::vector<int>{1, 2, 3}, 4, 5); // OK! Second function calls 'multi'
    tmp(1, std::vector<int>{2, 3}, 4);    // Compilation error! First function calls 'single'
    return 0;
}

编译器输出:

prog.cpp: In instantiation of ‘std::vector<int> tmp(int, types ...) [with types = {std::vector<int, std::allocator<int> >, int}]’:
prog.cpp:58:34:   required from here
prog.cpp:29:23: error: no matching function for call to ‘single(std::vector<int>&, std::vector<int>&, int&)’
  single(list, ints ...);
                       ^
prog.cpp:29:23: note: candidates are:
prog.cpp:12:6: note: void single(std::vector<int>&, int)
 void single(std::vector<int>& list, int first)
      ^
prog.cpp:12:6: note:   candidate expects 2 arguments, 3 provided
prog.cpp:18:6: note: template<class ... types> void single(std::vector<int>&, int, types ...)
 void single(std::vector<int>& list, int first, types ... ints)
      ^
prog.cpp:18:6: note:   template argument deduction/substitution failed:
prog.cpp:29:23: note:   cannot convert ‘ints#0’ (type ‘std::vector<int>’) to type ‘int’
  single(list, ints ...);
                       ^

我目前的实现:

#include <iostream>
#include <vector>
struct coordinate
{
    std::vector<int> c;
    coordinate(std::vector<int> A) : c(A) {}
    coordinate(int A) : c{A} {}
};
// Function to end the recursive call to single
void single(std::vector<int>& list, int first)
{
    list.push_back(first);
}
// Recursive function to store the parameters (only int)
template <typename... types>
void single(std::vector<int>& list, int first, types ... ints)
{
    list.push_back(first);
    single(list, ints ...);
}
// 'First' function
template <typename... types>
std::vector<int> tmp(int i, types ... ints)
{
    std::vector<int> list;
    list.push_back(i);
    single(list, ints ...);
    return list;
}
// Function to end the recursive call to multi
void multi(std::vector<std::vector<int> >& list, coordinate first)
{
    list.push_back(first.c);
}
// Recursive function for storing the parameters (only 'coordinate')
template <typename... types>
void multi(std::vector<std::vector<int> >& list, coordinate first, types ... coords)
{
    list.push_back(first.c);
    multi(list, coords ...);
}
// 'Second' function
template <typename... types>
std::vector<std::vector<int> > tmp(coordinate i, types ... coords)
{
    std::vector<std::vector<int> > list;
    list.push_back(i.c);
    multi(list, coords ...);
    return list;
}

好吧,根据我对评论的新理解,你想要这样的东西:

template <typename... Args>
typename std::enable_if<all_ints<Args...>::value>::type
tmp(Args... args) {
   // the all integer version
}
template <typename... Args>
typename std::enable_if<!all_ints<Args...>::value>::type
tmp(Args... args) {
   // the coordinate version
}

然后,您只需要编写类型trait来检查是否所有内容都是整数。

template <typename... T>
struct all_ints : std::true_type { };
template <typename T, typename... Rest>
struct all_ints<T, Rest...>
: std::integral_constant<bool, 
      std::is_integral<T>::value && all_ints<Rest...>::value>
{ }

我使用std::is_integal来处理所有的整数类型。如果你真的想要明确的int,你可以修复它。