【问题标题】:Perfect Forwarding in C++03C++03中的完美转发
【发布时间】:2011-04-05 05:52:31
【问题描述】:

如果你有这个功能

template<typename T> f(T&);

然后尝试调用它,比如说像这样的右值

f(1);

为什么不直接将 T 推导出为 const int,使参数成为 const int& 从而可绑定到右值?

【问题讨论】:

    标签: c++ forwarding c++03


    【解决方案1】:

    这在the document 中被提及为潜在的解决方案,我在recent C++0x forwarding question 中链接。

    工作得相当好,但它会破坏现有代码。考虑(直接来自文档):

    template<class A1> void f(A1 & a1)
    {
        std::cout << 1 << std::endl;
    }
    
    void f(long const &)
    {
        std::cout << 2 << std::endl;
    }
    
    int main()
    {
        f(5);              // prints 2 under the current rules, 1 after the change
        int const n(5);
        f(n);              // 1 in both cases
    }
    

    或者

    // helper function in a header
    
    template<class T> void something(T & t) // #1
    {
        t.something();
    }
    
    // source
    
    #include <vector>
    
    void something(bool) // #2
    {
    }
    
    int main()
    {
        std::vector<bool> v(5);
    
        // resolves to #2 under the current rules, #1 after the change
        something(v[0]);
    }
    

    这也无法转发值类别(左值或右值),这在 C++03 中不是什么大问题。但是由于这个修复只能在 C++0x 期间完成,所以我们在转发时有效地将自己与右值引用隔离开来(一件坏事)。我们应该努力寻求更好的解决方案。

    【讨论】:

      【解决方案2】:

      是的,但前提是你声明f 接受T const &amp;

      template <typename T> void f(T &);
      template <typename T> void g(T const &);
      
      void x() { f(1); }  // error: invalid initialization of non-const reference
      void y() { g(1); }  // no error
      

      如果你声明 both f(T &amp;)f(T const &amp;),它会选择 const 限定的:

      template <typename T> void f(T &);
      template <typename T> void f(T const &);
      
      void x() { f(1); } // no error, calls f(T const &)
      

      现在您可能会说“在第一个示例中,为什么它会为调用 f 生成一个 int 类型的临时文件,而它可以生成一个 @ 类型的临时文件987654329@ 并编译了代码?”我为您提供的最佳答案是,当参数不是整数常量时,这与重载解析行为不一致。

      【讨论】:

      • 是的,我知道超载。我想知道为什么它甚至是必要的。怎么会不一致?
      • @DeadMG: 1 的类型为 int。如果您声明了int i = 1,那么它将选择非常量方法,因为i 不是常量。因此,为了保持一致性,这里也是这样做的,只是对于右值,这是一个错误。
      • @Matthieu: 1 是一个 int 右值。 i 是一个 int 左值。既然语言坚持以不同的方式对待它们,那么它们就是不同的东西。因此,并不矛盾。事实上,有一堆专门针对右值的规则,然后在这里尝试同样对待它们是不一致的。
      • @DeadMG:我同意这个标准很奇怪,我个人认为1应该是int const类型,因为哎,我改不了!然而,这不是标准所说的那样,因此不是。至于禁止引用 rvalue 我永远不会喜欢它,从 C++ 哲学的角度来看这是没有意义的转发,对于类似“sink”的行为等),毕竟,为什么我不能修改一个临时的并对此感到满意呢?但标准就是法律,因此是一致的
      猜你喜欢
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 2017-08-05
      • 1970-01-01
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多