Template function with dependent type parameters within template class

萝らか妹 提交于 2019-12-13 00:47:23

问题


I've been trying to do this simple stuff and Visual studio 2008 does not seems 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 with something like this:

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

What I get is compiler errors stating that it can't deduce 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:


The compiler is simply unable to deduce types from this context.

Suppose std::wstring::const_iterator is actually const wchar_t*, which is likely. In that case, how does the compiler know it should substitute std::wstring rather than any other type T with T::const_iterator being const wchar_t* (perhaps vector<wchar_t>)?

It's impossible for the compiler to tell exactly. For similar reasons, you cannot deduce some_template<T>::type in function calls.

In your case, the workaround is easy. You don't actually need the container type - templating on the 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 the container type, you will have to either pass the container around or explicitly specify the type in the function call.




回答2:


The compiler can't deduce that the iterator parameters are actually inner type defs of the containers providing them.

Use directyl two iterator types:

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..
    }



回答3:


You probably need to be explicit about the types for SomeOperator:

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

I know that seems annoying, but it's actually fairly hard (and at times not possible) for the compiler to deduce the container type from a nested definition like T::const_iterator. Going from const_iterator back to T isn't straightforward AFAIK.



来源:https://stackoverflow.com/questions/1751915/template-function-with-dependent-type-parameters-within-template-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!