gpt4 book ai didi

c++ - 是否有任何库为不可默认构造的不可复制类型提供容器?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:43:51 26 4
gpt4 key购买 nike

我正在寻找一个提供容器的库,例如 std::array(编译时固定大小,但不支持聚合初始化)和 std::vector (可变大小,连续内存)适用于不可复制且不可默认构造的类型。

具体来说,我希望能够将一组函数传递给构造函数,这些函数用于获取所包含对象的构造函数的参数。类似于 emplace_back,但作为构造函数并使用惰性求值参数。

这是一个(自然不起作用的)示例:

class stubborn_type : boost::noncopyable {
public:
explicit stubborn_type(int value)
: value(value)
{}

private:
const int value;
};

struct generate_values {
generate_values(int initial_value = 0)
: current_value(initial_value)
{}

int operator()() {
return current_value++;
}
private:
int current_value;
};

/* This should create a vector containing 10 elements initialized with the values
[0..9] in order. */
magic::vector<stubborn_type> data(10, generate_values());

我需要解决方案与 C++03 兼容(因为这意味着没有可变参数模板,我更喜欢使用预处理器魔术为不同数量的参数生成重载的 Boost 方法,但合理的固定限制很好出色地)。这样的东西存在吗?如果没有,是否有任何库可以帮助实现该目标(例如,Boost.In Place Factory 几乎很有用,但它不支持惰性参数)。

最佳答案

我不知道有什么现成的解决方案,但是,做起来并不难。数组的轮廓可能看起来像这样

#include <cstddef>

typedef char saum;
// smallest addressable unit of memory

namespace magic {

template<class T>
class IArray
{
T *const _ptr;
const size_t _length;

public:

operator T* () {
return _ptr;
}

size_t length() const {
return _length;
}

private:

IArray<T>(T* ptr, size_t length)
: _ptr(ptr), _length(length)
{}

template<class S, size_t length>
friend class Array;
};


template<class T>
class Generator
{
public:
virtual void operator() (T* place) = 0;
};



template<class T, size_t length>
class Array
{
saum buffer[sizeof(T) * length];

public:

Array(Generator<T>& generate) {
for (size_t i = 0; i < length; i++)
generate((T*)buffer + i);
}
~Array() {
for (size_t i = 0; i < length; i++)
((T*)buffer)[i].~T();
}

operator IArray<T> () {
return IArray<T>((T*)buffer, length);
}

operator T* () {
return (T*)buffer;
}
};

}

我有点累了,请原谅我没有想出更好的名字。然而,它应该完成这项工作。也许,生成器的解决方案不是太漂亮,但仍然提供了灵 active 。我相信更多的羽毛不会造成问题。

一个例子

#include <new>
#include <iostream>

class Stubborn
{
public:
Stubborn(int value) : value(value*2) { }
const int value;

private:
Stubborn(const Stubborn&);
Stubborn& operator=(const Stubborn&);
};



struct StubbornGen : public magic::Generator<Stubborn>
{
StubbornGen() : current_value(0)
{}

void operator() (Stubborn* place) {
new(place) Stubborn(current_value++);
}

private:
int current_value;
};



void f(magic::IArray<Stubborn> stubs)
{
std::cout << stubs[0].value << stubs[1].value
<< stubs[2].value << stubs[3].value
<< " " << stubs.length() << std::endl;
}

int main(int argc, char *argv[])
{
StubbornGen gen;
magic::Array<Stubborn, 4> stubs(gen);
f(stubs);
}

编辑:已更正,感谢 DyP,加上生成器调整。

重要的是为 Array 定义复制构造函数和赋值运算符,以避免 DyP 指出的问题。 - 如何? - 取决于你想要什么。将它们设为私有(private)是一种方法。而进行非浅拷贝是另一回事。 - 在第二种情况下,模板实例化机制应该防止在将不可复制的类应用到数组时出错。

关于c++ - 是否有任何库为不可默认构造的不可复制类型提供容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16339418/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com