繁体   English   中英

规范包含编译时或运行时值的对象的构造

[英]Normalize construction of objects that contain compile-time *or* runtime values

可以说我有两节课

template <int A_, int B_>
class One {
    public:
        static constexpr auto A = A_;
        static constexpr auto B = B_;
        const int C;
        One(int C) : C(C) {}
};

class Two {
    public:
        const int A;
        const int B;
        const int C;
        Two(int A, int B, int C) : A(A), B(B), C(C) {}
};

唯一的区别是,类One在编译时采用AB参数,而类Two在运行时采用参数。 这些基本等效的类型上存在多种操作,因此可以将它们通用地编写:

template <typename T>
auto min(const T& a, const T& b) {
    if (a.C < b.C) {
        return T(a.A+b.A, a.B+b.B, a.C);
    } else {
        return T(a.A+b.A, a.B+b.B, b.C);
    }
}

上面的问题是输出对象的构造。 可以以相同的方式使用两种类型的OneTwo来访问ABC成员,获取它们的类型,等等。但是,因为对象的构造存在差异(馈送函数参数vs馈送模板参数),如果操作需要创建新对象,则不能通用地编写该对象。

我已经尝试了非类型模板参数推导,但是目前尚不可能 有没有办法解决? 还是我注定要复制代码?

您可以创建类似于std::integral_constant常量int类,但可以使用所需的函数进行扩展,例如:

template <int N> struct int_c
{
    static constexpr int value = N;
};

template <int N1, int N2>
constexpr int_c<N1 + N2> operator + (int_c<N1>, int_c<N2>) { return {}; }

template <int N>
std::ostream& operator << (std::ostream& os, int_c<N>) { return os << N; }

然后将您的类更改为具有近接口,尤其是对于构造函数,请添加工厂方法:

template <int A_, int B_>
class One {
public:
    static constexpr int_c<A_> A{};
    static constexpr int_c<B_> B{};
    const int C;
    One(int C) : C(C) {}

    template <typename IA, typename IB>
    static One<IA::value, IB::value> Create(IA, IB, int C) { return {C}; } 
};

class Two {
public:
    const int A;
    const int B;
    const int C;
    Two(int A, int B, int C) : A(A), B(B), C(C) {}

    static Two Create(int A, int B, int C) { return {A, B, C}; } 
};

然后,您的通用代码可能如下所示:

template <typename T1, typename T2>
auto min(const T1& a, const T2& b) {
    if (a.C < b.C) {
        return T1::Create(a.A + b.A, a.B + b.B, a.C);
    } else {
        return T1::Create(a.A + b.A, a.B + b.B, b.C);
    }
}

演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM