C++模板参数包传递给模板回调函数编译错误问题咨询
错误原因
- 模板参数推导冲突:
Function方法的模板参数TArgs需要同时从回调函数签名、传入的实参两个位置推导,两者类型不匹配导致推导失败。你定义的回调类型要求参数是TArgs&&转发引用,但你实际写的CBFunction1、CBFunction2的参数是值类型、左值const引用,和推导出来的TArgs类型无法匹配。你尝试使用type_identity_t但使用位置错误,应该给回调参数加type_identity_t修饰,让TArgs仅从后面的实参推导,避免两边推导冲突。 - const权限不匹配:
TestClass的成员data是const T类型,你直接传递给回调要求的T&非const左值引用,属于const权限放大,无法编译通过。
修复代码
首先需要引入<type_traits>头,然后调整CallbackFuncType的使用位置和回调参数签名,修改后的完整代码如下:
#include <iostream> #include <string> #include <type_traits> // 新增头文件 template<class T> class TestClass { public: template<typename ...TArgs> // 回调第一个参数调整为const T&,匹配data的const属性 using CallbackFuncType = bool(const T &Data, TArgs && ...Args); TestClass(const T &Data) : data(Data) {} template<typename ...TArgs> bool Function( // 给回调加type_identity_t,阻止从回调推导TArgs std::type_identity_t<CallbackFuncType<TArgs...>> Callback, TArgs && ...Args ) { return Callback(data, std::forward<TArgs>(Args)...); } private: const T data; }; struct DataType { int valInt; double valFloat; // ToString加const修饰,允许const对象调用 std::string ToString() const { return std::string( "valInt: " + std::to_string(valInt) + " valFloat: " + std::to_string(valFloat) ); } }; // 回调第一个参数改为const DataType& bool CBFunction1(const DataType &Data, int Arg0, const std::string &Arg1) { std::cout << "Data :" << Data.ToString() << std::endl; std::cout << "CBFunction1: " << "Arg0 : " << Arg0 << " Arg1: " << Arg1 << std::endl; return true; } // 回调第一个参数改为const DataType&,同时修复原代码Arg1输出为Arg0的笔误 bool CBFunction2(const DataType &Data, int Arg0, double Arg1, const std::string &Arg2) { std::cout << "Data :" << Data.ToString() << std::endl; std::cout << "CBFunction2: " << "Arg0 : " << Arg0 << " Arg1: " << Arg1 << " Arg2: " << Arg2 << std::endl; return true; } int main() { DataType data; data.valInt = 1; data.valFloat = 1.2; TestClass<DataType> testObj(data); std::cout << "test" << std::endl; std::cout << "call CBFunction1" << std::endl; bool val1 = testObj.Function(CBFunction1, 11, "test_string"); bool val2 = testObj.Function(CBFunction2, 11, 111.111, "test_string"); return 0; }
运行输出
test call CBFunction1 Data :valInt: 1 valFloat: 1.200000 CBFunction1: Arg0 : 11 Arg1: test_string Data :valInt: 1 valFloat: 1.200000 CBFunction2: Arg0 : 11 Arg1: 111.111000 Arg2: test_string
内容的提问来源于stack exchange,提问作者user2281752
相关产品推荐
相关产品推荐

