当我在模板函数的参数中使用方法指针时,我遇到了严重的模板类型推导问题。
让我们看下面的代码:
template <class ClassT, typename Arg1T>
inline void testTemplateFct(ClassT * clazz,
void (ClassT::*fctPtr)(Arg1T),
const Arg1T & arg1)
{
}
class TestClass
{
public:
void testMethodIntArg(int arg)
{}
void testMethodDoubleArg(double arg)
{}
void testMethodStringArg(const char * arg);
};
int main()
{
TestClass testClass;
testTemplateFct(&testClass,
&TestClass::testMethodIntArg,
10);
testTemplateFct(&testClass,
&TestClass::testMethodDoubleArg,
10.0);
/// BEGINNING OF MY PROBLEM
testTemplateFct(&testClass,
&TestClass::testMethodStringArg,
"a string...");
/// END OF MY PROBLEM
return 0;
}
如果我使用 g++ 编译它,我会收到以下错误消息:
$ g++ ArgumentDeduction.cpp -o ArgumentDeduction
ArgumentDeduction.cpp: In function ‘int main()’:
ArgumentDeduction.cpp:42:18: error: no matching function for call to ‘testTemplateFct(TestClass*, void (TestClass::*)(const char*), const char [12])’
"a string...");
^
ArgumentDeduction.cpp:4:13: note: candidate: template<class ClassT, class Arg1T> void testTemplateFct(ClassT*, void (ClassT::*)(Arg1T), const Arg1T&)
inline void testTemplateFct(ClassT * clazz,
^~~~~~~~~~~~~~~
ArgumentDeduction.cpp:4:13: note: template argument deduction/substitution failed:
ArgumentDeduction.cpp:42:18: note: deduced conflicting types for parameter ‘const Arg1T’ (‘const char*’ and ‘char [12]’)
"a string...");
如果我删除方法 testTemplateFct
的第三个参数的引用,问题就会消失(但是我绝对需要引用以避免复制)
template <class ClassT, typename Arg1T>
inline void testTemplateFct(ClassT * clazz,
void (ClassT::*fctPtr)(Arg1T),
const Arg1T arg1)
{}
我或多或少地理解了错误消息,但我不明白为什么 const char*
和 char [12]
之间存在歧义。我不明白为什么当我删除引用时问题消失了。
最后,我非常感谢任何帮助,以便在保留引用的同时更正此代码
PS: I know that I can "force" the type deduction by doing:
testTemplateFct(&testClass, &TestClass::testMethodStringArg, (const char *) "a string...");
but I don't like it very much
最佳答案
您的模板要求将出现的 Arg1T
推导为同一类型。我相信那不是你想要的。相反,类型应该独立推导:
template <class ClassT, typename Arg1T, typename GivenT>
inline void testTemplateFct(ClassT * clazz,
void (ClassT::*fctPtr)(Arg1T),
GivenT &&arg1)
{
//example use
(clazz->*fctPtr)(std::forward<GivenT>(arg1));
}
关于c++ - 使用模板、方法指针和字符串进行类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43573333/