草庐IT

c++ - 初始化不可复制和不可移动类的元组

coder 2024-02-22 原文

考虑具有唯一自定义构造函数的类 A:

class A
{
public:
    A(float) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

还有另一个类 B,它包含 A 的一个元组(为简单起见,让它成为唯一的元组成员):

class B
{
public:
    B() : ta(0.0f) {} // ta initialization OK

private:
    std::tuple<A> ta;
};

现在我们可以声明 B 的一个对象,它工作正常:

B b;

但是如果 A 的构造函数有多个参数,如何做同样的事情呢?

class A
{
public:
    A(float, int) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

class B
{
public:
//  B() : ta(0.0f, 1) {} // Compilation errors
//  B() : ta({0.0f, 1}) {} // Compilation errors
//  B() : ta{0.0f, 1} {} // Compilation errors
//  B() : ta(A(0.0f, 1)) {} // No constructor to copy or move A

private:
    std::tuple<A> ta;
};

B b;

std::make_tuplestd::forward_as_tuple 和其他类似的东西没有解决问题,因为 A<> 被禁用。

最佳答案

std::tuple 几乎没有就地构造其成员的工具。初始化 tuple 的普遍预期方式是通过从其组件对象复制/移动。

它确实允许将构造函数参数隐式转换为其各自的实参。但这只是参数和 tuple 成员之间的 1:1 关系。构造函数参数和 tuple 成员之间无法建立多对一关系。

可以允许您的类型可以从tuple 本身隐式构造:

class A
{
public:
    A(float, int) {}
    A(const std::tuple<float, int> &tpl)
        : A(std::get<0>(tpl), std::get<1>(tpl)) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

因此,您可以像这样构造一个元组:

class B
{
public:
    B() : ta(std::tuple<float, int>(0.0f, 1)) {}

private:
    std::tuple<A> ta;
};

如果你想使用更深层次的元编程,你可能还能够制作一组构造函数,允许你的类型从一个 tuple 构造,其类型匹配任何可用的构造函数:

class A
{
public:
    A(float, int) {}

    template<typename ...Args>
    A(const std::tuple<Args...> &args) : A(args, std::index_sequence_for<Args...>{}) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;

    template<typename ...Args, std::size_t ...Is>
    A(const std::tuple<Args...> &args, std::index_sequence<Is...>) 
        : A(std::get<Is>(args)...) {}
};

关于c++ - 初始化不可复制和不可移动类的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41657356/

有关c++ - 初始化不可复制和不可移动类的元组的更多相关文章

  1. 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”因此,为了解决

  2. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

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

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

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

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

  5. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  6. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  7. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  8. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  9. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  10. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

随机推荐