简体   繁体   English

VS2013中尝试部分专门化另一个模板的类模板时出现错误

[英]Error in VS2013 when attempting to partially specialize a class template with another class template

Given the following class and function templates: 给定以下类和函数模板:

template <typename WrappedType, ParameterType ParamType, bool IsOutputParameter>
    class WrappedParameter; // Definition left out for brevity

template <typename T>
struct ParameterUnwrapper
{
    static T UnwrapParameter(const T& in_param)
    {
        return in_param;
    }
};

template <typename T, ParameterType ParamType, bool IsOutputParameter>
struct ParameterUnwrapper<WrappedParameter<T, ParamType, IsOutputParameter>>
{
    static T UnwrapParameter(const WrappedParameter<T, ParamType, IsOutputParameter>& in_param)
    {
        return in_param.GetWrapped();
    }
};

template <typename T>
T UnwrapParameter(T in_param)
{
    return Impl::ParameterUnwrapper<T>::UnwrapParameter(in_param);
}

template <typename T>
Impl::WrappedParameter<T, Impl::POINTER_PARAMETER, true> WrapOutputPointerParameter(T in_param)
{
    return Impl::WrappedParameter<T, Impl::POINTER_PARAMETER, true>(in_param);
}

template <typename MemFunc, typename ...Args>
HRESULT ExecuteAndLog(
    MemFunc in_memberFunction,
    const std::string& in_methodName,
    Args... args) //-> decltype((m_wrapped->*in_memberFunction)(UnwrapParameter(args)...))
{
    return ExecuteFunctorAndLog(
        [&]() { return (m_wrapped->*in_memberFunction)(UnwrapParameter(args)...); },
        in_methodName,
        args...);
}

The following call: (The ExecuteAndLog) 以下调用:(ExecuteAndLog)

HRESULT STDMETHODCALLTYPE AccessorWrapper::AddRefAccessor(
    HACCESSOR hAccessor,
    DBREFCOUNT *pcRefCount)
{
    return ExecuteAndLog(
        &IAccessor::AddRefAccessor,
        "AddRefAccessor",
        hAccessor,
        WrapOutputPointerParameter(pcRefCount));
}

Gives me errors: 给我错误:

error C2664: 'HRESULT (HACCESSOR,DBREFCOUNT *)' : cannot convert argument 2 from 'Impl::WrappedParameter<DBREFCOUNT *,POINTER_PARAMETER,true>' to 'DBREFCOUNT *'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
see reference to function template instantiation 'ExecuteAndLog<HRESULT(__stdcall IAccessor::* )(HACCESSOR,DBREFCOUNT *),HACCESSOR, Impl::WrappedParameter<DBREFCOUNT *,POINTER_PARAMETER,true>>(MemFunc,const std::string &,HACCESSOR,Impl::WrappedParameter<DBREFCOUNT *,POINTER_PARAMETER,true>)' being compiled
with
[
    MemFunc=HRESULT (__stdcall IAccessor::* )(HACCESSOR,DBREFCOUNT *)
]
see reference to function template instantiation 'ExecuteAndLog<HRESULT(__stdcall IAccessor::* )(HACCESSOR,DBREFCOUNT *),HACCESSOR,Impl::WrappedParameter<DBREFCOUNT *,POINTER_PARAMETER,true>>(MemFunc,const std::string &,HACCESSOR,Impl::WrappedParameter<DBREFCOUNT *,POINTER_PARAMETER,true>)' being compiled
with
[
    MemFunc=HRESULT (__stdcall IAccessor::* )(HACCESSOR,DBREFCOUNT *)
]

I think I've messed up the partial specialization of ParameterUnwrapper (or my approach is just wrong). 我想我搞砸了ParameterUnwrapper的部分专业化(或者我的方法是错误的)。 Any advice? 有什么建议吗?

More information: 更多信息:

Impl is a nested namespace (alongside the namespace all the provided templates except ExecuteAndLog are in) Impl是一个嵌套的名称空间(除ExecuteAndLog外,所有提供的模板均位于该名称空间中)

m_wrapped is of type IAccessor* (the COM interface) in this case. 在这种情况下,m_wrapped的类型为IAccessor *(COM接口)。

        enum ParameterType
        {
            POINTER_PARAMETER,

            ARRAY_PARAMETER
        };

UPDATE: Here's a self contained example: http://codepad.org/lwTzVImb 更新:这是一个自包含的示例: http : //codepad.org/lwTzVImb

The error I get in VS2013 for this one is: 我在VS2013中遇到的错误是:

error C2664: 'int (int,int **,size_t *)' : cannot convert argument 2 from 'WrappedParameter<int **,ARRAY_PARAMETER,true>' to 'int **'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
see reference to function template instantiation 'int ExecuteAndLog<int(__thiscall A::* )(int,int **,size_t *),int,WrappedParameter<int **,ARRAY_PARAMETER,true>,size_t*>(MemFunc,const std::string &,int,WrappedParameter<int **,ARRAY_PARAMETER,true>,size_t *)' being compiled
with
[
    MemFunc=int (__thiscall A::* )(int,int **,size_t *)
]

I figured it out! 我想到了!

The issue was the return type of UnwrapParameter. 问题是UnwrapParameter的返回类型。 Once I changed the declaration of it to 一旦我将其声明更改为

    template <typename T>
    auto UnwrapParameter(T in_param) -> decltype(Impl::ParameterUnwrapper<T>::UnwrapParameter(in_param))

It compiled. 它编译了。 Shame the compiler didn't complain about the definition of that function, rather than trusting its declared return value. 令人遗憾的是,编译器没有抱怨该函数的定义,而不是信任其声明的返回值。

I have some other problems right now but at least I've made progress. 我现在还有其他一些问题,但至少我已经取得了进展。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM