9阅网

您现在的位置是:首页 > 知识 > 正文

知识

c++11 - c++11 在调用有N个args的函数之前,如何检查模板参数包是否有N个args?

admin2022-11-07知识17

继此之后 将不同类型的模板参数包提取到一个双数向量中会产生警告。 和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;

当有足够多的参数时,这应该选择非模板函数, 而在其他情况下则选择模板函数。