带有参考的模板包中推导的冲突类型

Tho*_*lik 5 c++ templates variadic-templates c++11 template-argument-deduction

我正在使用以下结构的程序:

#include <iostream>
#include <string>

void fun(const std::string &text, int a, int b) { // (1)
    std::cout << text << a + b << std::endl;
}

template<typename ...Args>
void execute(void(*fun)(Args...), Args ...args) {
    fun(args...);
}

void init(const std::string &text, int a, int b) {
    execute(fun, text, a, b);
}

int main() {
    init("Fun: ", 1, 2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我收到错误消息

.code.tio.cpp:14:2: error: no matching function for call to 'execute'
        execute(fun, text, a, b);
        ^~~~~~~
.code.tio.cpp:9:6: note: candidate template ignored: deduced conflicting types for parameter 'Args' (<const std::__cxx11::basic_string<char> &, int, int> vs. <std::__cxx11::basic_string<char>, int, int>)
void execute(void(*fun)(Args...), Args ...args) {
     ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

我可以通过删除第(1)行中的引用来修复错误:

void fun(const std::string text, int a, int b) {
Run Code Online (Sandbox Code Playgroud)

但是我想通过引用而不是通过值传递值。功能模板

template<typename ...Args>
void execute(void(*fun)(Args...), Args ...args)
Run Code Online (Sandbox Code Playgroud)

不得更改。我该如何解决这个问题,以便text通过引用传递, execute不更改,并且init在可能的情况下也不更改?

编辑:@super表明我错了,我必须重新制定自己的要求。execute只能在不依赖此功能的其他项目中断的范围内进行修改。我没有考虑过这样的解决方案。

Jod*_*cus 3

没有接触过execute,我想你必须改变init()。一种方法是显式传递模板参数(绕过参数推导以传输引用类型信息):

void init(const std::string &text, int a, int b) {
    execute<const std::string&>(fun, text, a, b);
}
Run Code Online (Sandbox Code Playgroud)