稍后添加模板函数的特殊化 [英] Adding specializations of template functions later

查看:116
本文介绍了稍后添加模板函数的特殊化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下函数:

  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
}

code> call_foo(),
call_foo()不使用重载。
但是,如果我在 call_foo()的定义之前移动过载代码,则会被使用。



为什么第一种情况下不使用过载?
在时间 call_foo()在代码中的其他地方被实例化,
编译器已经见过



请注意,我的原始代码有 foo()作为类似地使用 enable_if 保护的模板 foo_traits 的静态成员函数。即使在 call_foo()之后提供时, 代码有效,对于自由重载的函数?



如果重要的话,我在Mac OS X 10.7上使用 g ++ .4。

解决方案

如果你将标准(C ++ 98无论如何)改为14.6.4.2/1, / p>


对于依赖于模板参数的函数调用,如果
函数名称是非限定id, id,使用通常的查找规则(3.4.1,
3.4.2)找到
候选函数,除了:



部分查找使用不合格名称查找(3.4.1),
只有函数声明与模板
定义上下文的外部链接。


在这种情况下, template-id 表示< template-params> 模板名称。这几乎清楚地说明了你在程序中观察到的,只有在模板定义的上下文中可见的函数才被考虑。当你考虑它,如果不是这样的情况下,根据之后更改模板的意义是很容易的,导致违反一个定义规则。 p>

Suppose I have functions like:

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 );
}

This mostly works fine, but if I later add an overload for a particular type:

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

and I add it after the definition of call_foo(), the overload isn't used by call_foo(). However, if I move the overload code before the definition of call_foo(), it is used.

Why isn't the overload used in the first case? By the time call_foo() is instantiated at a point of use elsewhere in the code, the compiler has already seen the overload, so why doesn't it use it?

Note that my original code had the foo() functions as static member functions of a templated foo_traits classes similarly guarded using enable_if. That code worked, i.e., template class specializations, even when provided after call_foo() was used, so why not for free-standing overloaded functions?

If it matters, I'm using g++ 4.6 on Mac OS X 10.7.4.

解决方案

If you turn your standard (C++98 anyway) to 14.6.4.2/1 you read:

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.

In this case template-id means a <template-params> qualified template-name. This pretty much clearly states exactly what you observed in your program, that only functions visible in the context of the template definition are considered. And when you think about it, if this weren't the case it would be ridiculously easy to change meanings of a template based on what followed it, leading to a violation of the one definition rule.

这篇关于稍后添加模板函数的特殊化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆