草庐IT

c++ - 在 C++11 中,我可以为非聚合类型实现类似构造函数的聚合类型初始化吗?如何实现?

coder 2024-02-20 原文

比如说,我有一个封装在名为 stA

的类中的一维数组
class stA
{
public:
    template<typename ... T>
    stA(T ... t):
        data_{t...}
    {}

private:
    int data_[2];
};

通过利用可变参数模板,我可以成功实现这个想法。

stA a = {1, 2};

但是,当我试图将这个技巧应用于名为 stB 的类二维类时,

class stB
{
public:
    template<typename ... T>
    stB(T ... t):
        data_{t...}
    {}

private:
    stA data_[2];
};

诡计失败了。

stB b = {{1, 2}, {1, 2}};

error: could not convert '{{1, 2}, {1, 2}}' from brace-enclosed initializer list to 'stB' stB b = {{1, 2}, {1, 2}};

一开始这让我很困惑。

因为如果 stB::Ctor 中的 template-argument-deduction 导致 T = const stA &,那么 Ctor 会变成这样,

stB(const stA & a, const stA & b):
        data_{a, b}
    {}

当然 stB b = {{1, 2}, {1, 2}}; 会存活下来,但会失去一些参数的灵 active 。

经过一番搜索,我终于意识到这可能违反了模板参数推导的规则,

Non-deduced contexts

6) The parameter P, whose A is a braced-init-list, but P is not std::initializer_list, a reference to one (possibly cv-qualified), or a reference to an array:

但我还在徘徊 是否还有办法实现这个想法?如何实现?

最佳答案

问题是 {1, 2} 不是表达式,只能推导表达式。

选项 1:使用聚合初始化。使 data_ 成员公开,聚合初始化允许您初始化元素。缺点:控制力差。

选项 2:使用 initializer_list。如:

class stA {
public:
    stA(std::initializer_list<int> init):
        data_{init.begin()[0], init.begin()[1]}
    {
        assert(init.size() == 2);
    }

private:
    int data_[2];
};

class stB {
public:
    stB(std::initializer_list<std::initializer_list<int>> init):
        data_{init.begin()[0], init.begin()[1]}
    {
        assert(init.size() == 2);
    }

private:
    stA data_[2];
};

缺点:大小信息在编译时丢失。

选项 3:使用聚合类型作为构造函数参数。

class stA {
public:
    stA(const int (&arr)[2]):
        data_{arr[0], arr[1]}
    {
    }

private:
    int data_[2];
};

class stB {
public:
    stB(const int (&arr)[2][2]):
        data_{arr[0], arr[1]}
    {
    }

private:
    stA data_[2];
};

(这需要一对额外的大括号,如 stB b = {{{1, 2}, {3, 4}}};。)

关于c++ - 在 C++11 中,我可以为非聚合类型实现类似构造函数的聚合类型初始化吗?如何实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57252228/

有关c++ - 在 C++11 中,我可以为非聚合类型实现类似构造函数的聚合类型初始化吗?如何实现?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  3. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  4. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

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

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

  6. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  7. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  8. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  9. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  10. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

随机推荐