为模板函数专门化启用_if 我在C++中使用装饰器模式。在使事情像在一本书中那样工作之后,我决定创建一个模板函数(称为“decoration”),以帮助我基于decorator类、concrete类和interface类构建装饰对象

为模板函数专门化启用_if 我在C++中使用装饰器模式。在使事情像在一本书中那样工作之后,我决定创建一个模板函数(称为“decoration”),以帮助我基于decorator类、concrete类和interface类构建装饰对象,c++,C++,基本的模板功能运行良好。但后来我决定,我还希望有一个decorator类的空实现,它除了调用具体的对象方法之外,不做任何其他事情。这是有效的,我可以坚持这种设计,但我不太满意的是,当使用空的装饰器时,我仍然会在那里进行虚拟调用,实际上除了调用另一个虚拟方法外,它什么也不做。我希望避免这种不必要的间接操作,并决定专门化我的模板函数,以便在使用空装饰器时,它返回未装饰的对象(具体对象)。 我想使用enable_if专门化我的模板函数,但不知为什么它不想编译。我一定是做错了什么。请帮帮我。我下面的代码

基本的模板功能运行良好。但后来我决定,我还希望有一个decorator类的空实现,它除了调用具体的对象方法之外,不做任何其他事情。这是有效的,我可以坚持这种设计,但我不太满意的是,当使用空的装饰器时,我仍然会在那里进行虚拟调用,实际上除了调用另一个虚拟方法外,它什么也不做。我希望避免这种不必要的间接操作,并决定专门化我的模板函数,以便在使用空装饰器时,它返回未装饰的对象(具体对象)。 我想使用enable_if专门化我的模板函数,但不知为什么它不想编译。我一定是做错了什么。请帮帮我。我下面的代码有什么问题

#include <iostream>
#include <memory>
#include <type_traits>
using namespace std;

struct IA {
    virtual ~IA() {}
    virtual void doSth() = 0;
};

struct ConcreteA : public IA
{
    void doSth() override 
    {
         cout << "concrete: doSth" << endl;
    }
};

struct LoggingDecoratorA : public IA {
    LoggingDecoratorA(unique_ptr<IA> pia) : _pia(move(pia)) {}
    void doSth() override 
    {
         cout << "calling doSth" << endl;
        _pia->doSth();
    }
    unique_ptr<IA> _pia;
};

struct EmptyDecoratorA : public IA {
    EmptyDecoratorA(unique_ptr<IA> pia) : _pia(move(pia)) {}
    void doSth() override 
    {
        _pia->doSth();
    }
    unique_ptr<IA> _pia;
};

void fun(IA* pia)
{
    pia->doSth();
}

template<typename Decorator, typename Concrete, typename Interface, typename X = enable_if_t<!is_same<Decorator, EmptyDecoratorA>::value>>
unique_ptr<Interface> decorate()
{
    return make_unique<Decorator>((make_unique<Concrete>()));
}

template<typename Decorator, typename Concrete, typename Interface, typename X = void>
unique_ptr<Interface> decorate()
{
    return make_unique<Concrete>();
}

int main()
{ 
    auto pia = decorate<LoggingDecoratorA, ConcreteA, IA>();
    fun(pia.get());
}
#包括
#包括
#包括
使用名称空间std;
结构IA{
虚拟~IA(){}
虚空doSth()=0;
};
结构混凝土A:公共IA
{
void doSth()重写
{
库特
独特的装饰()
{
返回make_unique((make_unique());
}
模板
独特的装饰()
{
返回make_unique();
}
int main()
{ 
自动pia=装饰();
乐趣(pia.get());
}
试试这个:

template<typename Decorator, typename Concrete, typename Interface>
typename enable_if<is_same<Decorator, EmptyDecoratorA>::value, unique_ptr<Interface>>::type
decorate()
{
    return make_unique<Decorator>((make_unique<Concrete>()));
}

template<typename Decorator, typename Concrete, typename Interface>
typename enable_if<!is_same<Decorator, EmptyDecoratorA>::value, unique_ptr<Interface>>::type
decorate()
{
    return make_unique<Concrete>();
}
模板
typename启用_if::type
装饰
{
返回make_unique((make_unique());
}
模板
typename启用\如果::值,唯一的\ ptr>::类型
装饰
{
返回make_unique();
}
模板>
独特的装饰()
{
返回make_unique((make_unique());
}
模板
独特的装饰()
{
返回make_unique();
}
SFINAE不是这样工作的(默认模板类型参数不是函数签名的一部分,请检查此项以了解更多详细信息)

您可以按如下方式更改代码:

template<typename Decorator, typename Concrete, typename Interface>
auto decorate() ->
    enable_if_t<!is_same<Decorator, EmptyDecoratorA>::value, unique_ptr<Interface>>
{
    return make_unique<Decorator>((make_unique<Concrete>()));
}


template<typename Decorator, typename Concrete, typename Interface>
auto decorate() ->
    enable_if_t<is_same<Decorator, EmptyDecoratorA>::value, unique_ptr<Interface>>
{
    return make_unique<Concrete>();
}
模板
自动装饰()->
启用\u如果\u t::值,唯一\u ptr>
{
返回make_unique((make_unique());
}
模板
自动装饰()->
启用\u如果\u t
{
返回make_unique();
}
并将
std::enable_if_t
移动到返回类型。现在正确应用了SFINAE,因为返回类型是函数签名的一部分

template<typename Decorator, typename Concrete, typename Interface>
auto decorate() ->
    enable_if_t<!is_same<Decorator, EmptyDecoratorA>::value, unique_ptr<Interface>>
{
    return make_unique<Decorator>((make_unique<Concrete>()));
}


template<typename Decorator, typename Concrete, typename Interface>
auto decorate() ->
    enable_if_t<is_same<Decorator, EmptyDecoratorA>::value, unique_ptr<Interface>>
{
    return make_unique<Concrete>();
}