直接或通过构造函数初始化类型的类

initialize class with same type directly or through constructor

本文关键字:初始化 类型 构造函数      更新时间:2023-10-16

我有此代码:

#include <iostream>
template <int mult>
struct A {
    int v;
    A (int p) {
        v = p * mult;
    }
};
int main (void) {
    A<4> a (2); // initialize v = 2 * 4
    A<4> b = {2}; // initialize v to 2
    std::cout << a.v << " " << b.v << std::endl;
}

我想看" 8 2"。我得到的是" 8 8"。

我希望通过构造函数或通过其他某些方法避免构造函数来初始化V的方法。我已经研究了initializer_list或汇总初始化,但是我还没有找到解决方案。唯一的黑客是创建一个带有虚拟额外参数的新构造函数。

任何更好的方法?

首先,您应该更喜欢成员初始化列表,而不是在构造函数的主体中分配,即

A (int p): v(p * mult) {}

第二,如果这是一个XY问题,我建议您遵循其他答案并更改设计。正如Deidei在评论中指出的那样,界面现在尚不清楚。

如果您仍然坚持此设计,则可以继续阅读。


您可以使用以std::initializer_list为参数的构造函数。当对象被列表至少化时,首先将考虑此类构造函数。例如:

#include <initializer_list>
template <int mult>
struct A {
    int v;
    A (int p): v(p * mult) {}
    A (std::initializer_list<int> l) : v(*l.begin()) {}
};

缺陷是无法在编译时确定std::initializer_list的大小,因此您必须接受大小大于1的列表初始化器或大小0的列表初始化器,这会导致表达式*l.begin()中的不确定行为。

当然,您可以进行一些运行时检查,例如,

A (std::initializer_list<int> l) {
    if (l.size() != 1) {
        /* do something */
    }
    v = *l.begin();
}

但是,您必须遭受此支票造成的效率损失。

您可以保留一个私有构造函数,并使用静态方法来对待其参数不同:

template <int mult>
class A {
    int v;
    A (int p) {
        v = p;
    }
public:
    static A<mult> constructor1(int p) {
        return A<mult>(p);
    }
    static A<mult> constructor2(int p) {
        return A<mult>(p * mult);
    }
};

我发现最好的解决方案是为'int v'创建一个容器类。类似:

#include <iostream>
struct Ac {
    int v;
};
template <int mult>
struct A : Ac {
    A (Ac p) {
        v = p.v;
    }
    A (int p) {
        v = p * mult;
    }
};
int main (void) {
    A<4> a (2); // initialize v = 2 * 4
    A<4> b = (Ac{2}); // initialize v to 2
    std::cout << a.v << " " << b.v << std::endl;
}
相关文章: