Template function with dependent type parameters in a template class

I tried to make this simple stuff, and Visual Studio 2008 did not seem to like it.

template <class CharType> class SomeClass { public: template <class T1, class T2> static bool SomeOperator(const typename T1::const_iterator& p_Begin1, const typename T1::const_iterator& p_End1, const typename T2::const_iterator& p_Begin2, const typename T2::const_iterator& p_End2) { // do some stuff.. } }; 

And call it something like this:

 std::wstring a; OtherString b; SomeClass<wchar_t>::SomeOperator(a.begin(), a.end(), b.begin(), b.end()); 

I get compiler errors stating that it cannot output the template parameter T1 and T2

 error C2783: 'bool SomeClass<CharType>::SomeOperator(const T1::const_iterator &,const T1::const_iterator &,const T2::const_iterator &,const T2::const_iterator &)' : could not deduce template argument for 'T1' error C2783: 'bool SomeClass<CharType>::SomeOperator(const T1::const_iterator &,const T1::const_iterator &,const T2::const_iterator &,const T2::const_iterator &)' : could not deduce template argument for 'T2' 
+1
source share
3 answers

The compiler simply cannot infer types from this context.

Suppose std::wstring::const_iterator is actually const wchar_t* , which is likely. In this case, how does the compiler know that it should replace std::wstring , and not any other type T with T::const_iterator equal to const wchar_t* (possibly vector<wchar_t> )?

It is impossible for the compiler to tell exactly. For similar reasons, you cannot output some_template<T>::type to function calls.

In your case, the workaround is simple. You really don't need a container type - templates on iterator types will work fine:

 template <typename I1, typename I2> static bool SomeOperator(const I1& p_Begin1, const I1& p_End1, const I2& p_Begin2, const I2& p_End2) { /* stuff */ } 

If you find yourself in a situation where you need a container type, you will have to either pass the container or explicitly specify the type of function call.

+3
source

The compiler cannot infer that the parameters of the iterator are actually internal types of defs of the containers that provide them.

Use directyl two types of iterator:

 template< typename IT1, typename IT2> static bool SomeOperator(const IT1& p_Begin1, const IT1& p_End1, const IT2& p_Begin2, const IT2& p_End2) { // do some stuff.. } 
+1
source

You probably need to explicitly specify the types for SomeOperator :

 SomeClass<wchar_t>::SomeOperator<std::wstring, std::wstring>(a.begin(), a.end(), b.begin(), b.end()); 

I know this seems annoying, but it is actually quite difficult (and sometimes impossible) for the compiler to deduce the type of the container from the nested definition of type T::const_iterator . Going from const_iterator back to T not a direct AFAIK.

0
source

All Articles