c++ - 使用模板、方法指针和字符串进行类型推导

标签 c++ templates type-deduction template-argument-deduction

当我在模板函数的参数中使用方法指针时,我遇到了严重的模板类型推导问题。

让我们看下面的代码:

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/

相关文章:

c++ - fatal error : string: No such file or directory compilation terminated

c++ - 连续内存、OpenGL,以及如何包装顶点?

C++:纯虚拟类型

javascript - Summernote - 插入带有 Angular Directive(指令)的模板

c++ - 从一种类型转换为另一种类型时的模板类型推导

c++ - 从模板基类派生时找不到类型

C++ 以<输入文件和>输出文件启动程序

具有纯虚运算符+函数的 C++ 抽象基类

c++ - 派生类中的模板有问题

C++ 入门(第五版): Is "16.3 Overloading and Templates" wrong in all its "more specialized" examples?