我正在编写两个具有相同名称的函数(并且具有相似的参数):
第一个只采用可变数量的整数参数(最小一个)。
第二个采用可变量struct coordinate
作为参数(再次最小值为1)。
struct coordinate
可以从int
和std::vector<int>
构建,因此第二个也可以采用int
和std::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;
}
答案 0 :(得分:1)
好的,基于我对评论的新理解,你想要这样的东西:
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
}
然后你只需要编写类型特征来检查是否所有内容都是整数。
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
,你可以解决它。