在C ++中调用基本成员函数模板模糊性

我试图实现一个DependencyInjectable行为,从这种行为派生的类能够在实例化时注入适当的依赖关系。

下面我试图从一个更大的项目中提取和压缩代码样本来说明我遇到的问题。 这有点冗长,我为此道歉。

#include <tuple>
#include <type_traits>

template <typename, typename> struct tuple_has_type;
template <typename T> struct tuple_has_type<T, std::tuple<>> : std::false_type { };
template <typename T, typename U, typename ... Args> struct tuple_has_type<T, std::tuple<U, Args ...>> : tuple_has_type<T, std::tuple<Args ...>> { };
template <typename T, typename ... Args> struct tuple_has_type<T, std::tuple<T, Args ...>> : std::true_type { };

template<typename ... Dependencies>
class DependencyInjectable
{
private:

    template<int index, typename ... Args>
    struct assign_dependencies
    {
        void operator () (std::tuple<Dependencies ...> &lhs, std::tuple<Args ...> &&rhs)
        {
            typedef typename std::tuple_element<index, std::tuple<Dependencies ...>>::type T;
            std::get<T>(lhs) = std::get<T>(rhs);
            assign_dependencies<index - 1, Args ...> { } (lhs, std::forward<std::tuple<Args ...>>(rhs));
        }
    };

    template<typename ... Args>
    struct assign_dependencies<0, Args ...>
    {
        void operator() (std::tuple<Dependencies ...> &lhs, std::tuple<Args ...> &&rhs)
        {
            typedef typename std::tuple_element<0, std::tuple<Dependencies ...>>::type T;
            std::get<T>(lhs) = std::get<T>(rhs);
        }
    };

public:

    template<typename ... Args>
    DependencyInjectable(Args ... dependencies)
    {
        setDependencies(std::forward<Args>(dependencies) ...);
    }

    virtual ~DependencyInjectable(void) { }

    template<typename T> auto getDependency(void) const ->
        typename std::enable_if<tuple_has_type<T, std::tuple<Dependencies ...>>::value, T>::type
    {
        return std::get<T>(m_dependencies);
    }

    template<typename T, typename U = typename std::decay<T>::type>
    auto setDependency(T &&dependency) ->
        typename std::enable_if<tuple_has_type<U, std::tuple<Dependencies ...>>::value, void>::type
    {
        std::get<U>(m_dependencies) = dependency;
    }

    template<typename ... Args>
    void setDependencies(Args ... dependencies)
    {
        constexpr auto size = std::tuple_size<std::tuple<Dependencies ...>>::value;
        static_assert(size > 0, "List of dependencies must be specified.");
        assign_dependencies<size - 1, Args ...> { } (m_dependencies, std::forward_as_tuple(
            std::forward<Args>(dependencies) ...));
    }

private:

    std::tuple<Dependencies ...> m_dependencies; // an std::tuple containing injection dependencies
};

class DependencyOfBase { };
class DependencyOfDerived { };

class Base
    : public DependencyInjectable<DependencyOfBase *>
{
public:

    Base(DependencyOfBase *pDependencyOfBase)
        : DependencyInjectable<DependencyOfBase *>(pDependencyOfBase)
    {

    }

    virtual ~Base(void) { }
};

class Derived
    : public Base, public DependencyInjectable<DependencyOfDerived *>
{
public:

    using Base::getDependency;
    using DependencyInjectable<DependencyOfDerived *>::getDependency;

    Derived(DependencyOfBase *pDependencyOfBase, DependencyOfDerived *pDependencyOfDerived)
        : Base(pDependencyOfBase),
        DependencyInjectable<DependencyOfDerived *>(pDependencyOfDerived)
    {

    }

    virtual ~Derived(void) { }
};

int main(int argc, char **argv)
{
    DependencyOfBase dependencyOfBase;
    DependencyOfDerived dependencyOfDerived;

    Base base(&dependencyOfBase);
    Derived derived(&dependencyOfBase, &dependencyOfDerived);

    auto *pDependencyOfBase = base.getDependency<DependencyOfBase *>();
    auto *pDependencyOfDerived = derived.getDependency<DependencyOfDerived *>();

    return (pDependencyOfBase != nullptr && pDependencyOfDerived != nullptr) ? 0 : 1;
}

特别是,我使用std :: tuple在DependencyInjectable类中存储依赖关系,并且当元组不包含请求的类型时,我试图使用enable_if来禁用getDependency()函数。 主要的是,我调用了Derived的getDependency()函数实例,并指定了“DependencyOfDerived *”。 这只要我指定就行

using Base::getDependency;
using DependencyInjectable<DependencyOfDerived *>::getDependency; 

在Derived类中,但我会认为enable_if会禁用基于“DependencyOfDerived *”模板参数的getDependency()函数,因为Base元组不包含该类型。 我在这里错过了什么?

如果我评论使用语句,这是我从gcc获得的以下输出:

在函数'int main(int,char **)'中:116:42:error:成员'getDependency'的请求不明确45:31:注意:候选项是:template typename std :: enable_if> :: value,T> :: type DependencyInjectable :: getDependency()const [with T = T; 依赖关系= {DependencyOfDerived *}] 45:31:note:template typename std :: enable_if> :: value,T> :: type DependencyInjectable :: getDependency()const [with T = T; Dependencies = {DependencyOfBase *}] 116:76:错误:预期在'*'标记之前的主表达式116:77:错误:预期在'>'标记之前的主表达式116:79:错误:预期的主表达式之前') '令牌

链接地址: http://www.djcxy.com/p/90141.html

上一篇: Call to base member function template ambiguity in C++

下一篇: Accessing private values in cpp using pointers