c++ - 编译器选择了错误的模板函数特化

标签 c++ templates

我拼命想让我的特化工作,但由于推导出不正确的参数,我仍然有不可编译的代码。请注意,错误与定义模板无关,而是与在错误的模板实现中应用不相关的操作有关。演示问题的代码的简化示例是:

struct Test { void Method() const {} };

template<typename T>
void Cmp(T _val) { _val > 1; }

template<>
void Cmp<const Test &>(const Test &_val) { _val.Method(); }

template<>
void Cmp<const char *>(const char *_val) { _val[2]; }

int main()
{
  Test test1;
  char test2[5];

  Cmp(10);    // ok, expected
  Cmp(test1); // error in Cmp(T)?! but expecting to instantiate Cmp(const Test &)
  Cmp(test2); // error in Cmp(T)?! but expecting to instantiate Cmp(const char *)
  return 0;
}

我真的不想使用像 Cmp<const Test &>(test1) 这样的显式调用(有效)作为 AFAIK,编译器应该能够自动推断出参数,并且这些特化背后的整个想法是透明地分派(dispatch) Cmp 调用(在实际代码中,我正在定义运算符)。当然是按值特化Cmp<Test>(Test)按预期工作,但对于大型复杂的非 POD 类,按值传递它是荒谬的。

无论我尝试应用什么修复程序,编译器都顽固地拒绝使用通用模板来选择按引用特化。似乎我遗漏了一些重要的东西,但我真的想不出为什么我的方法不起作用,以及我应该如何构建代码来表达非模板化 C++ 世界中这样一个简单的概念,如通过引用传递类。当然,谷歌被证明对这个问题毫无用处。 ^_^ 我试过 GCC 4.2.1 和 4.4.6。

最佳答案

Cmp(test1);

此处,T 是从参数推导出来的 Test。它未被推断为 const Test& 因此您的特化不匹配,因此主模板被实例化的原因。您需要使您的特化按值进行 Test。通过此声明,确实使用了特化:

template<>
void Cmp<Test>(Test _val) { _val.Method(); }

Cmp(test1);

此处,T 被推导为char*,而不是const char*,因此特化不匹配。您需要专门针对 char* 而不是 const char* 来匹配它。或者,您可以在调用时将参数转换为 const char*:

const char* test2ptr = test2;
Cmp(test2ptr); 

综上所述,既然可以重载,为什么还要专攻呢?

template<typename T>
void Cmp(T _val) { _val > 1; }

void Cmp(const Test &_val) { _val.Method(); }

void Cmp(const char *_val) { _val[2]; }

// Add an overload to support arrays of char:
template <unsigned N>
void Cmp(const char (&_val)[N]) { _val[1]; }

You really should avoid specializing function templates.这很困难,而且在大多数情况下不值得这么麻烦。

关于c++ - 编译器选择了错误的模板函数特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6420268/

相关文章:

C++,继承模板嵌套类

java - 在 Windows 7 上为 JNI_CreateJavaVM 链接到什么库?

c++ - 错误 : expected ‘,’ or ‘...’ before ‘for’ in #define

c++ - 模板父类(super class)的静态成员定义

C++ 代码风格 : SHA2 algorithm

c++ - 迭代器和模板

c++ - wglShareLists 失败并出现错误 6 : ERROR_INVALID_HANDLE The handle is invalid

c++ - 代码无法识别 "#include"语句

c++ - `const T` 与 T = char* 不是 `const char*` 吗?

html - 如何在 Flask 中导入 html 模板?