【发布时间】:2017-04-23 15:56:24
【问题描述】:
我在模板函数的参数中使用方法指针时遇到了严重的模板类型推导问题。
让我们看下面的代码:
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:我知道我可以通过这样做“强制”类型推导:
testTemplateFct(&testClass, &TestClass::testMethodStringArg, (const char *) "a string...");但我不是很喜欢它
【问题讨论】:
-
你有多不喜欢
testTemplateFct(&testClass, &TestClass::testMethodStringArg, +"a string...");? -
更好。但是,它绕过了我的问题,但并没有解决它
标签: c++ templates type-deduction template-argument-deduction