使用模板、方法指针和字符串键入推导
Type deduction with template, method pointer and strings
当我在模板函数的参数中使用方法指针时,我遇到了严重的模板类型推断问题。
让我们采用以下代码:
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...");
但我不太喜欢它
您的模板要求将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));
}
我不明白为什么
const char*
和char [12]
之间存在歧义.
请注意,"a string..."
是类型为const char[12]
的数组。对于函数模板testTemplateFct
,参数arg1
被声明为引用,即const Arg1T &
,那么数组到指针衰减不会发生在模板参数推导中,Arg1T
被推导为char[12]
,这与从第二个参数推导的Arg1T
类型不匹配,即const char*
,所以推论失败。
我不明白为什么当我删除引用时问题消失了。
当参数被声明为按值传递数组到指针衰减时;那么从第二个和第三个参数推导出的Arg1T
类型都将const char*
,一切正常。
您有两个基本选项。
第一个是将调用更改为:
testTemplateFct(&testClass,
&TestClass::testMethodStringArg,
(const char *)"a string...");
第二个选项是添加重载:
template <class ClassT, size_t n>
inline void testTemplateFct(ClassT * clazz,
void (ClassT::*fctPtr)(const char *),
const char (&arg1)[n])
{
testTemplateFct<ClassT, const char *>(clazz, fctPtr, arg1);
}
选择最适合您的一种。
文字字符串实际上是一个const char[n]
,而不是一个const char *
。const char
数组在普通函数调用中衰减为const char *
;但这种衰减不会作为模板演绎的一部分发生;因此问题来了。
- strcpy 在类中无法使用字符串指针
- 如何将字符串指针数组转换为字符串类型的智能指针向量?
- 使用conststd::字符串指针作为函数参数
- 将字符串指针传递到C++和Xcode 11.1中不同线程上运行的函数
- OOP 和字符串指针的奇怪行为
- 在 C++ 中通过字符串指针复制字符串变量中的字符串
- 删除字符串指针在struct中的内存
- 字符串指针的排序向量
- C#C /CLR处理REF参数和字符串指针
- 问题在字符串指针中存储单词
- 如何在C++中从字符串指针中获取字符
- 如何使用字符串指针访问映射的键
- 将字符串指针与 NULL 以及 NULL 字符进行比较的目的
- 如何获取字符串指针的值?
- C++ 字符串* 指针未在控制台中正确打印
- Visual Studio C++ 空字符串指针
- 管理C#中返回的字符串指针
- 指向C++中的字符串指针数组的指针
- 如何将结果集设置为字符串指针
- 如何初始化字符串指针