c++ - 稍后添加模板函数的特化

标签 c++ templates template-specialization

假设我有这样的功能:

template<typename T> inline
typename std::enable_if<has_member_foo<T>::value,int>::type
foo( T const &t ) {
  return t.foo();
}

template<typename T> inline
typename std::enable_if<!has_member_foo<T>::value,int>::type
foo( T const& ) {
  return 0;
}

template<typename T> inline
int call_foo( T const &t ) {
  return sizeof( T ) + foo( t );
}

这大部分工作正常,但如果我稍后为特定类型添加重载:

inline int foo( std::string const &s ) {
  return s.size();
}

然后我在 call_foo() 的定义之后添加它, call_foo() 不使用重载。 但是,如果我将重载代码移到 call_foo() 的定义之前,它就会被使用。

为什么第一种情况不使用重载? 当 call_foo() 在代码中其他地方的使用点被实例化时, 编译器已经看到重载, 那为什么不使用它呢?

请注意,我的原始代码将 foo() 函数作为模板化 foo_traits 类的静态成员函数,同样使用 enable_if 进行保护。 代码有效,即模板类特化,即使在 call_foo() 被使用时也是如此,所以为什么不为独立的重载函数提供?

如果重要的话,我在 Mac OS X 10.7.4 上使用 g++ 4.6。

最佳答案

如果您将标准(C++98 无论如何)转换为 14.6.4.2/1,您将阅读:

For a function call that depends on a template parameter, if the function name is an unqualified-id but not a template-id, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2) except that:

— For the part of the lookup using unqualified name lookup (3.4.1), only function declarations with external linkage from the template definition context are found.

在这种情况下 template-id表示 <template-params>合格的模板名称。这非常清楚地说明了您在程序中观察到的内容,即仅考虑在模板定义的上下文中可见的函数。当您考虑一下时,如果不是这种情况,根据遵循的内容更改模板的含义将非常容易,从而导致违反单一定义规则。 p>

关于c++ - 稍后添加模板函数的特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11453737/

相关文章:

C++ |如何在函数结果中返回所有 PID?

c++ - 从 main 调用函数时出错

c++ - 如何将 char[] 的前两个字节从网络字节序转换为主机字节序?

C++模板类编译错误: expected init-declarator before '<' token

c++ - 任何 vector 的特化

c++ - C++ 类中的任何泛型类型

c++ - 为什么除非我添加括号,否则构造函数上的模板替换会失败?

c++ - 如何为 std::list 重载 std::remove ?

c++ - '仅将成员函数添加到类的专用模板

c++ - 函数特化 : Which is the declaration?