将具有不同类型的模板参数包提取到双精度向量中会产生警告

extracting a template parameter pack with different types into a vector of doubles produces warnings

我正在尝试将大量 class 基本相同但采用不同数量参数的元素转换为单个模板 class。所以我创建了一个模板 class 示例(不是真正的代码 - 仅作为示例):

// The template type
template<typename... Args>
class tester_template
{
public:
    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 (well enough for me anyway). But I get a lot of "narrowing" warnings
        // this is understandable, but I want to have no warnings (some sort of cast on a 
        // parameter pack??)
        std::vector<double> args_vect = {args...};
        for (auto arg : args_vect)
        {
            std::cout << arg << " ";
        }
        std::cout << std::endl;
    };
};

我运行这样的:

// Same with one template class
tester_template<double> template1;
tester_template<int, int> template2;
tester_template<int, int, int> template3;
tester_template<float> template4;
tester_template<float, double, int> template5;

template1.process(1.123);           // ok
template2.process(2, 2);            // Warnings
template3.process(3, 2, 3);         // Warnings
template4.process(4.4f);            // Warnings 
template5.process(5.5f, 2.234, 3);  // Warnings

此处包含警告的完整示例以及模板 class 替换的先前许多 class 示例:https://rextester.com/RBEA68379

所以我理解error/warning消息(基本上如果我转换我可能会丢失数据)。但我想抑制警告 - 也许通过铸造。但我不知道如何使用参数包执行此操作 - 也许我遗漏了它,但我没有在网上找到它。

我猜的两个问题:

  1. 我可以放弃(或其他不会关闭警告的方法)吗?
  2. 我只是想把参数包提取到一个我可以迭代的结构中,我这样做是明智的,还是有更好的方法?

是的,您可以轻松地转换参数:

std::vector<double> args_vect = {static_cast<double>(args)...};

并且没有发出警告。

这里是 demo

正如@NathanOliver 在评论中指出的那样,如果您只想打印所有可变参数,您可以这样做:

void process(Args... args)
{
   ((std::cout << args << " "), ...);
   std::cout << std::endl;
};

那么您就不必担心任何类型的转化。

这里是 demo

您还可以使用 sizeof... 计算传入参数的数量,并使用该信息分派给采用固定数量参数的函数:

void process1arg(double ) {}
void process2arg(double , double ) {}
void process3arg(double , double  , double ) {}

void process(Args... args)
{  
    ((std::cout << args << " "), ...);
    std::cout << std::endl;

    if constexpr (sizeof...(args) == 1)
       process1arg(args...);
    if constexpr (sizeof...(args) == 2)
       process2arg(args...);
    if constexpr (sizeof...(args) == 3)
       process3arg(args...);
};

请注意,您需要 if constexpr 而不是常规的 if,否则当参数数量不匹配时代码将无法编译。

这是一个demo