c++ - 尝试使用另一个类模板部分特化类模板时 VS2013 出错

标签 c++ templates visual-studio-2013 template-specialization

给定以下类和函数模板:

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

以下调用:(ExecuteAndLog)

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

给我错误:

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 *)
]

我想我弄乱了 ParameterUnwrapper 的部分特化(或者我的方法是错误的)。有什么建议吗?

更多信息:

Impl 是一个嵌套的命名空间(除了 ExecuteAndLog 之外,所有提供的模板都在命名空间旁边)

在这种情况下,m_wrapped 是 IAccessor* 类型(COM 接口(interface))。

        enum ParameterType
        {
            POINTER_PARAMETER,

            ARRAY_PARAMETER
        };

更新: 这是一个独立的示例:http://codepad.org/lwTzVImb

我在 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 *)
]

最佳答案

我想通了!

问题是 UnwrapParameter 的返回类型。一旦我将它的声明更改为

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

已编译。可惜编译器没有提示该函数的定义,而是相信它声明的返回值。

我现在还有一些其他问题,但至少我已经取得了进步。

关于c++ - 尝试使用另一个类模板部分特化类模板时 VS2013 出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24923335/

相关文章:

C++模板静态类代码生成

c# - Visual Studio 2013 构建缓慢 启动缓慢

c++ - 如何正确使用作为其他定义参数的定义? C++

c++ - 条件变量和#pragma pack bug

c++ - 模板函数中的静态变量似乎不是模板实例所独有的

visual-studio-2013 - Visual Studio 2013 网站项目 - 在配置管理器中更改配置

c++ - 是否可以将 Cinder 与 VS2013 一起使用?

c++ - 这种获取模板参数包中最后一个元素的方法是否有隐藏的开销?

c++ - Mac OS X 上的 Qt : How to get rid of QListView's blue outline?

c++ - 如何使用 std::enable_if_t 进行完美转发?