【发布时间】:2019-06-24 10:22:36
【问题描述】:
以下代码无法编译,因为编译器推断模板参数为int,而它需要为int &。在 Coliru here 上查看。
#include <iostream>
#include <utility>
template <class F, class... ArgsType>
void do_something(F f, ArgsType... args)
{
f(std::forward<ArgsType>(args)...);
}
int main()
{
int s = 2;
int i = 1;
auto add = [](const int a, int& sum) { sum += a; };
do_something(add, i, s);
std::cout << s << std::endl;
return 0;
}
错误:
main.cpp: In instantiation of 'void do_something(F, ArgsType ...) [with F = main()::<lambda(int, int&)>; ArgsType = {int, int}]':
main.cpp:15:27: required from here
main.cpp:7:6: error: no match for call to '(main()::<lambda(int, int&)>) (int, int)'
f(std::forward<ArgsType>(args)...);
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:7:6: note: candidate: 'void (*)(int, int&)' <conversion>
main.cpp:7:6: note: conversion of argument 3 would be ill-formed:
main.cpp:7:6: error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
main.cpp:14:40: note: candidate: 'main()::<lambda(int, int&)>' <near match>
auto add = [](const int a, int& sum) { sum += a; };
^
main.cpp:14:40: note: conversion of argument 2 would be ill-formed:
main.cpp:7:6: error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
f(std::forward<ArgsType>(args)...);
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
理想情况下,do_something 的第三个参数应该推导出为int&。一种方法是将模板参数显式传递为
#include <iostream>
#include <utility>
template <class F, class... ArgsType>
void do_something(F f, ArgsType... args)
{
f(std::forward<ArgsType>(args)...);
}
int main()
{
int s = 2;
int i = 1;
auto add = [](const int a, int& sum) { sum += a; };
do_something<decltype(add), const int, int&>(add, i, s);
std::cout << s << std::endl;
return 0;
}
在 Coliru here 上查看。
虽然该解决方案有效,但我觉得它很不方便,因为它迫使我提供do_something 的所有 模板类型,这不是最优的,特别是如果我有一个更复杂的示例几个参数,或者如果我想直接插入 lambda 函数 add 作为参数
do_something:
do_something([](const int a, int& sum) { sum += a; }, i, s);
有没有更方便的方法来强制仅将第三个参数推导出为int &?
【问题讨论】:
标签: c++ c++11 templates template-argument-deduction