草庐IT

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

coder 2024-02-05 原文

我正在寻找一个提供容器的库,例如 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/

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

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  5. ruby-on-rails - link_to 不显示任何 rails - 2

    我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article

  6. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  7. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  8. ruby - 检查日期是否在过去 7 天内 - 2

    我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/

  9. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  10. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

随机推荐