<legend id='SpBfL'><style id='SpBfL'><dir id='SpBfL'><q id='SpBfL'></q></dir></style></legend>

<tfoot id='SpBfL'></tfoot>

        • <bdo id='SpBfL'></bdo><ul id='SpBfL'></ul>
      1. <i id='SpBfL'><tr id='SpBfL'><dt id='SpBfL'><q id='SpBfL'><span id='SpBfL'><b id='SpBfL'><form id='SpBfL'><ins id='SpBfL'></ins><ul id='SpBfL'></ul><sub id='SpBfL'></sub></form><legend id='SpBfL'></legend><bdo id='SpBfL'><pre id='SpBfL'><center id='SpBfL'></center></pre></bdo></b><th id='SpBfL'></th></span></q></dt></tr></i><div id='SpBfL'><tfoot id='SpBfL'></tfoot><dl id='SpBfL'><fieldset id='SpBfL'></fieldset></dl></div>
      2. <small id='SpBfL'></small><noframes id='SpBfL'>

        后备可变参数构造函数 - 为什么这有效?

        时间:2023-05-24
        <tfoot id='TEUkI'></tfoot>
          • <bdo id='TEUkI'></bdo><ul id='TEUkI'></ul>

                <tbody id='TEUkI'></tbody>
              <i id='TEUkI'><tr id='TEUkI'><dt id='TEUkI'><q id='TEUkI'><span id='TEUkI'><b id='TEUkI'><form id='TEUkI'><ins id='TEUkI'></ins><ul id='TEUkI'></ul><sub id='TEUkI'></sub></form><legend id='TEUkI'></legend><bdo id='TEUkI'><pre id='TEUkI'><center id='TEUkI'></center></pre></bdo></b><th id='TEUkI'></th></span></q></dt></tr></i><div id='TEUkI'><tfoot id='TEUkI'></tfoot><dl id='TEUkI'><fieldset id='TEUkI'></fieldset></dl></div>

                • <small id='TEUkI'></small><noframes id='TEUkI'>

                  <legend id='TEUkI'><style id='TEUkI'><dir id='TEUkI'><q id='TEUkI'></q></dir></style></legend>
                  本文介绍了后备可变参数构造函数 - 为什么这有效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  限时送ChatGPT账号..

                  在回答这个问题时,关于尝试构造一个可变参数转发引用构造函数,只有在没有其他构造函数时才应调用该构造函数有效的.也就是说,如果有:

                  In answering this question about trying to construct a variadic forwarding reference constructor that should only be called if no other constructor is valid. That is, if there was a:

                  C(const char*, size_t) { }                     // 1
                  template <typename... T, ???> C(T&&... ) { }   // 2
                  

                  我们希望 C c1{"abc", 2}; 调用 (1),尽管需要转换,但是 C c2{1, 2, 3}; 调用 (2),因为 (1) 不适用.

                  We'd want C c1{"abc", 2}; to call (1), despite the required conversion, but C c2{1, 2, 3}; to call (2), as (1) cannot apply.

                  我提出了以下解决方案:

                  I proposed the following solution:

                  template <typename... T,
                            typename = std::enable_if_t<!std::is_constructible<C, T&&...>::value>
                             >
                  C(T&&... ) { }
                  

                  我的意思是说,我尝试过并惊讶地发现它确实有效.它编译并完成了我对 gcc 和 clang 的期望.但是,我无法解释为什么它起作用,或者即使它实际上应该起作用,而且 gcc 和 clang 都特别包容.是吗?为什么?

                  And by proposed, I mean, I tried it and was surprised to discover that it actually works. It compiles and does exactly what I had hoped for on both gcc and clang. However, I am at a loss to explain why it works or even if it's actually supposed to work and gcc and clang are both just being particularly accommodating. Is it? Why?

                  推荐答案

                  你的代码的问题是我们只是在一个上下文中实例化了 is_constructible它得到了错误的答案.模板代码中的任何类型的缓存都可能导致错误——尝试在调用构造函数后在相同的参数上打印 is_constructible!很可能会弄错.

                  The issue with your code is that we just instantiated is_constructible in a context where it gets the answer wrong. Any kind of caching in the template code is likely to result in bugs -- try printing is_constructible on the same parameters after you call the constructor! It is likely to get it wrong.

                  现场示例,说明如何出错.请注意,它声称 C 不能从 int& 构造,尽管在前一行已经这样做了.

                  Live example of how it can go wrong. Notice it claims C cannot be constructed from an int&, despite having done so on the previous line.

                  struct C {
                    C(const char*, size_t) {}
                    template <class... Ts,
                      typename = std::enable_if_t<!std::is_constructible<C, Ts&&...>::value>
                    >
                    C(Ts&&... ) { }
                  };
                  
                  int main() {
                    int a = 0;
                    C x{a};
                    std::cout << std::is_constructible<C, int&>{} << '
                  ';
                  }
                  

                  糟糕.

                  我怀疑这可能是 ODR 违规——is_constructible 的两个定义在不同的位置有不同的类型?或者也许不是.

                  I suspect this might be an ODR violation -- the two definitions of is_constructible have different types at different spots? Or maybe not.

                  没有这个问题的原始问题的解决方案也贴出来了.

                  这篇关于后备可变参数构造函数 - 为什么这有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:为什么 C++ 模板定义需要在头文件中? 下一篇:Lambda 和 std::function

                  相关文章

                  最新文章

                  • <bdo id='dhcQq'></bdo><ul id='dhcQq'></ul>

                    <small id='dhcQq'></small><noframes id='dhcQq'>

                    <tfoot id='dhcQq'></tfoot>
                    <i id='dhcQq'><tr id='dhcQq'><dt id='dhcQq'><q id='dhcQq'><span id='dhcQq'><b id='dhcQq'><form id='dhcQq'><ins id='dhcQq'></ins><ul id='dhcQq'></ul><sub id='dhcQq'></sub></form><legend id='dhcQq'></legend><bdo id='dhcQq'><pre id='dhcQq'><center id='dhcQq'></center></pre></bdo></b><th id='dhcQq'></th></span></q></dt></tr></i><div id='dhcQq'><tfoot id='dhcQq'></tfoot><dl id='dhcQq'><fieldset id='dhcQq'></fieldset></dl></div>

                      <legend id='dhcQq'><style id='dhcQq'><dir id='dhcQq'><q id='dhcQq'></q></dir></style></legend>