问题描述:

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.

相关阅读:
Top