Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"ambiguous call to overloaded function" when using variadic templates in VS2013

Given the following code:

        template <typename T>
        bool TryQueryInterface(
            IUnknown* in_toQuery,
            REFIID riid,
            void **ppvObject,
            ComObject* in_parent,
            HRESULT out_result)
        {
            if (InterfaceProperties<T>::GetIID() == riid)
            {
                void *underlying;
                HRESULT result = in_toQuery->QueryInterface(riid, &underlying);
                if (SUCCEEDED(result))
                {
                    *ppvObject = new typename InterfaceProperties<T>::WrapperClass(
                        *this,
                        (T*)underlying,
                        in_parent);
                }

                return true;
            }

            return false;
        }

        template <typename T, typename... Interfaces>
        bool TryQueryInterfaces(
            IUnknown* in_toQuery,
            REFIID riid,
            void **ppvObject,
            ComObject* in_parent,
            HRESULT out_result)
        {
            return TryQueryInterface<T>(in_toQuery, riid, ppvObject, in_parent, out_result) ||
                   TryQueryInterfaces<Interfaces...>(in_toQuery, riid, ppvObject, in_parent, out_result);
        }

        template <typename T>
        bool TryQueryInterfaces(
            IUnknown* in_toQuery,
            REFIID riid,
            void **ppvObject,
            ComObject* in_parent,
            HRESULT out_result)
        {
            return TryQueryInterface<T>(in_toQuery, riid, ppvObject, in_parent, out_result);
        }

I'm getting the following error:

    error C2668: 'TryQueryInterfaces' : ambiguous call to overloaded function
TryQueryInterfaces<ITrusteeGroupAdmin>(IUnknown *,const IID &,void **,ComObject *,HRESULT)'
 or       TryQueryInterfaces<ITrusteeGroupAdmin,>(IUnknown *,const IID &,void **,ComObject *,HRESULT)'
          while trying to match the argument list '(IUnknown *, const IID, void **, ComObject *, HRESULT)'
see reference to function template instantiation 'bool TryQueryInterfaces<ITrusteeAdmin,ITrusteeGroupAdmin>(IUnknown *,const IID &,void **,ComObject *,HRESULT)' being compiled

What am I missing here? How do I construct an unambiguous base case for the recursion?

like image 373
Bwmat Avatar asked Sep 01 '25 10:09

Bwmat


1 Answers

It's ambiguous because the parameter pack Interfaces... could be empty. Make sure that you take at least one argument plus a number of additional (possibly zero) parameters. Change the second method to:

template <typename T, typename Interface, typename... Interfaces>
bool TryQueryInterfaces(
    IUnknown* in_toQuery,
    REFIID riid,
    void **ppvObject,
    ComObject* in_parent,
    HRESULT out_result)
{
    return TryQueryInterface<T>(in_toQuery, riid, ppvObject, in_parent, out_result) ||
           TryQueryInterfaces<Interface, Interfaces...>(in_toQuery, riid, ppvObject, in_parent, out_result);
}
like image 86
Daniel Frey Avatar answered Sep 04 '25 00:09

Daniel Frey