c++11 - c++11 在调用有N个args的函数之前,如何检查模板参数包是否有N个args?
继此之后 将不同类型的模板参数包提取到一个双数向量中会产生警告。 和cigien的回答。
我有以下代码。
enum class p_type {p1, p2, p3};
class testerx
{
public:
void process1(double a)
{
std::cout << "1" << a << std::endl;
};
void process2(double a, double b)
{
std::cout << "2" << a << " " << b << std::endl;
};
void process3(double a, double b, double c)
{
std::cout << "3" << a << " " << b << " " << c << std::endl;
};
};
// The template type
template<typename TESTER, typename... ARGS>
class tester_templatex
{
public:
explicit tester_templatex(p_type type) : m_type(type) {};
void process(ARGS... args)
{
// Create a vector to put the args into. use double since that can hold all of the types
// that I am using
size_t param_count = sizeof...(args);
std::cout << "PARAM COUNT X " << param_count << std::endl;
std::vector<double> args_vect = {static_cast<double>(args)...};
for (auto arg : args_vect)
{
std::cout << "arg: " << arg << std::endl;
}
// Now call the tester
std::cout << "running tester: ";
switch (m_type)
{
case p_type::p1:
if constexpr (sizeof...(args) == 1)
m_tester.process1(args...);
break;
case p_type::p2:
if constexpr (sizeof...(args) == 2)
m_tester.process2(args...);
break;
case p_type::p3:
if constexpr (sizeof...(args) == 3)
m_tester.process3(args...);
break;
}
std::cout << std::endl;
};
p_type m_type;
TESTER m_tester;
};
main:
int main() {
tester_templatex<testerx, int> templatex1(p_type::p1);
tester_templatex<testerx, int, double> templatex2(p_type::p2);
tester_templatex<testerx, int, double, int> templatex3(p_type::p3);
templatex1.process(4);
templatex2.process(4, 5.123);
templatex3.process(4, 5.123, 6);
return 0;
}
这里我有一个测试类,有三个不同的函数。我有一个模板类,它根据函数的 p_type
(名字不好听--别问!)。
这对c++17编译后的代码是有效的,但我只有c++11需要运行这段代码。但我只有c++11需要运行这段代码,c++11不支持 if constexpr
:
case p_type::p3:
if constexpr (sizeof...(args) == 3)
m_tester.process3(args...);
break;
无 if constexpr
我得到的错误是 m_tester.process1/2/3
函数,因为参数数量不对,所以不符合参数包。
- 请问c++11如何解决这个问题?- 是否可以用类似的方法?
- c++11中有没有其他方法可以从参数包中提取N个参数?- 或者某种类型特征检查?
【回答】:
对你的每个函数都有一个什么都不做的重载。
template<typename... ARGS>
void process3(ARGS&...) { }
然后只调用函数而不测试包的大小。
case p_type::p3:
m_tester.process3(args...);
break;
当有足够多的参数时,这应该选择非模板函数, 而在其他情况下则选择模板函数。