简体   繁体   English

如何使具有引用数据成员的类可以在没有参数的情况下构造?

[英]How can I make a Class with reference data member constructible with no arguments?

I have a class, say C, where one of the member data, say X, depends on user input.我有一个类,比如 C,其中一个成员数据,比如 X,取决于用户输入。 The user input may differ on every run, and in my current design, all instances of my classes stores a reference to the same object X.每次运行时用户输入可能不同,在我当前的设计中,我的类的所有实例都存储对同一对象 X 的引用。

How can I tweak the design so that it allows default constructor with no arguments?如何调整设计以允许没有参数的默认构造函数?

This way I can use copy assignment/copy constructor, make arrays of C, use temporary rvalue etc.这样我就可以使用复制赋值/复制构造函数,制作 C 数组,使用临时右值等。

Below is a minimal working example illustrating my question.以下是说明我的问题的最小工作示例。 In the case I work with, Tag refers to some external resources.在我使用的情况下,Tag 指的是一些外部资源。

#include <iostream>
#include <string>
#include <vector>
#include <cassert>

using namespace std;

struct Tag {
    int N;
    string tag;
};

template<typename T>
struct Vec {
    const Tag& tag;
    T* vec;

    Vec(const Tag& tag_) : tag(tag_) {
        vec = new T[tag.N];
    }

    ~Vec() {
        delete [] vec;
    }
};

Tag make_tag(vector<string>& args) {
    assert(args.size() == 3);
    int N = stoi(args[1]);
    return Tag {N, args[2]};
}

vector<string> arguments(int argc, char* argv[]) {
    vector<string> res;
    for(int i = 0; i < argc; i++)
        res.push_back(argv[i]);
    return res; 
}

int main(int argc, char* argv[]) {
    vector<string> args = arguments(argc, argv);
    Tag tag0 = make_tag(args);
    Tag tag1;
    Vec<double> vec(tag0);
    return 0;
}

How can I tweak the design so that it allows default constructor with no arguments?如何调整设计以允许没有参数的默认构造函数?

Well, three options that I would suggest:好吧,我建议的三个选项:

  • The fancy way : Use a std::optional<std::reference_wrapper<T>> member.奇特的方法:使用std::optional<std::reference_wrapper<T>>成员。 std::reference_wrapper is for putting reference in place where you're not sure a reference would just work as-is. std::reference_wrapper用于在您不确定引用是否按原样工作的地方放置引用。 std::optional<T> holds either a T or a nullopt (ie no-value). std::optional<T>持有Tnullopt (即无值)。 This has the benefit of the default initializer for the optional being argument-less, so you can possibly use a default constructor for the argument-less case of C.这有一个好处是optional的默认初始化器是无参数的,所以你可以为 C 的无参数情况使用默认构造函数。

  • The old-school way : Use a plain pointer member instead of the reference.老派方式:使用普通指针成员而不是引用。 Initialize it to nullptr on no-argument construction.在无参数构造上将其初始化为nullptr (@RemyLebeau also suggested this in a comment.) (@RemyLebeau 也在评论中提出了这一点。)

  • The smart-ass RAII way : Replace your class C with an std::optional<C> .聪明的 RAII 方式:用std::optional<C>替换你的类C This means that argument-less construction doesn't actually construct a C - it just keeps a nullopt , delaying the actual construction for later.这意味着无参数构造实际上并不构造 C - 它只是保留一个nullopt ,将实际构造推迟到以后。 This solution is relevant when you must maintain the invariant of C holding resources throughout its existence;当您必须在整个存在期间保持C持有资源的不变性时,此解决方案是相关的; it also has the benefit of keeping the reference member of C as const .它还具有将C的引用成员保持为const的好处。

I purposely am not considering your MWE (you said it is just illustrative), and am offering a more general answer.我故意不考虑您的 MWE(您说这只是说明性的),而是提供更一般的答案。

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

相关问题 我可以检查一个类是*不是*默认可构造的吗? - Can I check that a class is *not* default constructible? 如何正确初始化非默认可构造的类成员? - How to properly initialize non-default-constructible class member? 如何检查 class 是否可以从多个 arguments 显式构造? - How to check if a class if explicitly constructible from multiple arguments? 如何使用 std::reference_wrapper 作为 class 成员? - How can I use std::reference_wrapper as a class member? 如何将对`std :: cout`的引用存储为类成员 - How can I store a reference to `std::cout` as a class member 如何通过绑定另一个成员函数的参数来制作C ++成员函数? - How can I make a C++ member function by binding the arguments of another member function? 我可以让参考成员不占空间吗? - Can I make a reference member no space taken? 非constexpr可构造类的constexpr成员函数 - constexpr member function of non constexpr constructible class 如果另一个类的构造函数需要参数,我如何添加一个类成员? - How can I add a class member if the other class' constructor requires arguments? 默认情况下,我如何在带有类参数的情况下携带类模板成员的实现? - How can i carry the implementation of a member of a class template with arguments by default out of boundary this class template?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM