Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+;中对基成员函数模板的调用不明确+;_C++_Inheritance_Dependency Injection_Ambiguity_Name Conflict - Fatal编程技术网

C++ C+;中对基成员函数模板的调用不明确+;

C++ C+;中对基成员函数模板的调用不明确+;,c++,inheritance,dependency-injection,ambiguity,name-conflict,C++,Inheritance,Dependency Injection,Ambiguity,Name Conflict,我正在尝试实现DependencyInjectable行为,从该行为派生的类可以在实例化时注入适当的依赖项 下面,我试图从一个更大的项目中提取并浓缩一个代码示例,以说明我遇到的问题。有点长,我为此道歉 #include <tuple> #include <type_traits> template <typename, typename> struct tuple_has_type; template <typename T> struct tu

我正在尝试实现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;
}
#包括
#包括
模板结构元组\u具有\u类型;
模板结构元组_具有_类型:std::false_类型{};
模板结构tuple_具有类型:tuple_具有类型{};
模板结构元组_具有_类型:std::true_类型{};
模板
类依赖可注入
{
私人:
模板
结构分配依赖项
{
void操作符()(std::tuple和lhs,std::tuple和rhs)
{
typedef typename std::tuple_元素::type T;
std::get(lhs)=std::get(rhs);
分配_依赖项{}(lhs,std::forward(rhs));
}
};
模板
结构分配依赖项
{
void操作符()
{
typedef typename std::tuple_元素::type T;
std::get(lhs)=std::get(rhs);
}
};
公众:
模板
DependencyInjectable(Args…dependencies)
{
setDependencies(std::forward(dependencies)…);
}
虚~DependencyInjectable(void){}
模板自动获取依赖项(void)常量->
typename std::enable_if::type
{
返回std::get(m_依赖项);
}
模板
自动设置依赖项(T&&dependency)->
typename std::enable_if::type
{
std::get(m_依赖项)=依赖项;
}
模板
void setDependencies(Args…dependencies)
{
constexpr auto size=std::tuple\u size::value;
静态_断言(大小>0,“必须指定依赖项列表”);
将_依赖项{}(m_依赖项,std::forward_作为_元组(
标准::转发(依赖项)…);
}
私人:
std::tuple m_dependencies;//包含注入依赖项的std::tuple
};
基{}的类依赖关系;
派生的{}的类依赖关系;
阶级基础
:public dependency可注入
{
公众:
基础(依赖于基础*pDependencyOfBase)
:DependencyInjectable(pDependencyOfBase)
{
}
虚~Base(void){}
};
类派生
:public Base,public dependency可注入
{
公众:
使用Base::getDependency;
使用DependencyInjectable::getDependency;
派生(依赖于数据库*pDependencyOfBase,依赖于派生*pDependencyOfDerived)
:基础(pDependencyOfBase),
依赖性可注射(pDependencyOfDerived)
{
}
虚~导出(空){}
};
int main(int argc,字符**argv)
{
基础的依赖性基础的依赖性;
派生的从属关系派生的从属关系;
基础(和基础的依赖关系);
派生的(&dependencyOfBase,&dependencyOfDerived);
auto*pDependencyOfBase=base.getDependency();
auto*pDependencyOfDerived=derived.getDependency();
返回值(pDependencyOfBase!=nullptr&&pDependencyOfDerived!=nullptr)?0:1;
}
特别是,我使用std::tuple在DependencyInjectable类中存储依赖项,并尝试在tuple不包含请求的类型时使用enable_if禁用getDependency()函数。在main中,我调用派生函数的getDependency()函数的实例,并指定“DependencyOfDerived*”。只要我指定,它就可以工作

using Base::getDependency;
using DependencyInjectable<DependencyOfDerived *>::getDependency; 
使用Base::getDependency;
使用DependencyInjectable::getDependency;
在派生类中,但我认为enable_if会在基元组中为“DependencyOfDerived*”模板参数禁用getDependency()函数,因为基元组不包含该类型。我错过了什么

如果我对using语句进行注释,这是我从gcc获得的以下输出:

在函数“int main(int,char**)”中: 116:42:错误:对成员“getDependency”的请求不明确 45:31:注意:候选项是:模板typename std::enable_if>::value,T>::type DependencyInjectable::getDependency()const[带T=T;Dependency={DependencyOfDerived*}] 45:31:注意:模板typename std::enable_if>::value,T>::type DependencyInjectable::getDependency()const[带T=T;Dependency={DependencyOfBase*}] 116:76:错误:应在“*”标记之前使用主表达式 116:77:错误:在“>”标记之前应该有主表达式
116:79:错误:在“')”标记之前应该有一个主表达式,如果没有这些
using
语句,会出现什么错误?我编辑了上面的帖子,以包含从gcc获得的错误消息,如果我没有包含using语句。谢谢你指出这一点。