基于C ++策略的变量型返回值设计

时间:2014-03-07 03:10:03

标签: c++ templates

我想使用基于策略的设计来根据我正在使用的策略更改主机类的返回类型。这是一个例子:

class IntPolicy {
public:
    int doIntPolicy(double anInput) {
        return static_cast<int>(anInput);
    }
};

class DoublePolicy {
public:
    double doDoublePolicy(int anInput) {
        return static_cast<double>(anInput);
    }
};

template<typename IntPolicyType, typename DoublePolicyType>
class SimpleHost {

private:
    IntPolicyType _intPolicy;
    DoublePolicyType _doublePolicy;

public:

    template<typename InputType>
    auto doHost(InputType input) -> decltype(_doublePolicy.doDoublePolicy(_intPolicy.doIntPolicy(input))) {
        auto aVar =  _intPolicy.doIntPolicy(input);
        return _doublePolicy.doDoublePolicy(aVar);
    }


};

以下是我如何使用主机类和策略:

typedef SimpleHost<IntPolicy, DoublePolicy> Host;
Host host;
auto theOutput = host.doHost(5);

虽然这会编译并运行,但请注意我必须将doHost方法的主体放在decltype函数中,以便编译器可以推导出尾随返回。如果doHost函数的主体很大,那么这看起来会非常难看。有什么办法可以避免这种情况吗?

2 个答案:

答案 0 :(得分:0)

如果您不喜欢它的外观,那么可能尝试定义?

#define RECURSE_POLICY(E) policy2.doPolicy(policy1.doPolicy(E)) 
template<typename InputType>
auto doHost(InputType input) -> decltype(RECURSE_POLICY(input)) {
    return RECURSE_POLICY(input);
}

话虽如此,你不得不两次调用doPolicy看起来不对。也许你可以重构它。

答案 1 :(得分:0)

1.-扩展模板

#include <stdio.h>
#include <string>
#include <iostream>

class IntPolicy {
public:
    int doIntPolicy(double anInput=NULL) {
        if(!NULL)
        {
            return static_cast<int>(anInput);
        }
        else
        {
            return -1;
        }
    }
};

class DoublePolicy {
public:
    double doDoublePolicy(int anInput=NULL) {
        if(!NULL)
        {
            return static_cast<double>(anInput);
        }
        else
        {
            return -1;
        }
    }

};



template<typename IntPolicyType, typename DoublePolicyType,
    class __Type >
class SimpleHost {

private:
    IntPolicyType _intPolicy;
    DoublePolicyType _doublePolicy;

public:

    template<typename InputType>
    auto doHost(InputType input) -> __Type {
        auto aVar =  _intPolicy.doIntPolicy(input);
        return _doublePolicy.doDoublePolicy(aVar);
    }



};

int main()
{
    IntPolicy foo;
    DoublePolicy bar;
    typedef SimpleHost<IntPolicy, DoublePolicy, 
        decltype(bar.doDoublePolicy(foo.doIntPolicy()))> Host;
    Host host;
    auto theOutput = host.doHost(5);

    return 0;
}

2.-最简单的方法是重命名impl,如果您使用的是外部库,可以考虑将其包装用于此目的

class IntPolicy {
public:
    int doPolicy(double anInput) {
        return static_cast<int>(anInput);
    }
};

class DoublePolicy {
public:
    double doPolicy(int anInput) {
        return static_cast<double>(anInput);
    }

};



template<typename IntPolicyType, typename DoublePolicyType>
class SimpleHost {

private:
    IntPolicyType _intPolicy;
    DoublePolicyType _doublePolicy;

public:

    template<typename InputType>
    auto doHost(InputType input) -> decltype(_doublePolicy.doPolicy(_intPolicy.doPolicy(input))) 
    {
        auto aVar =  IntPolicyType.doPolicy(input);
        return DoublePolicyType.doPolicy(aVar);
    }

但为了真正帮助你,我们需要你试图调用的特定功能,我的意思是我觉得这已经是一团糟了。