将具有不同类型的模板参数包提取到双精度向量中会产生警告
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消息(基本上如果我转换我可能会丢失数据)。但我想抑制警告 - 也许通过铸造。但我不知道如何使用参数包执行此操作 - 也许我遗漏了它,但我没有在网上找到它。
我猜的两个问题:
- 我可以放弃(或其他不会关闭警告的方法)吗?
- 我只是想把参数包提取到一个我可以迭代的结构中,我这样做是明智的,还是有更好的方法?
是的,您可以轻松地转换参数:
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。
我正在尝试将大量 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消息(基本上如果我转换我可能会丢失数据)。但我想抑制警告 - 也许通过铸造。但我不知道如何使用参数包执行此操作 - 也许我遗漏了它,但我没有在网上找到它。
我猜的两个问题:
- 我可以放弃(或其他不会关闭警告的方法)吗?
- 我只是想把参数包提取到一个我可以迭代的结构中,我这样做是明智的,还是有更好的方法?
是的,您可以轻松地转换参数:
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。