代码之家  ›  专栏  ›  技术社区  ›  John

为什么两个不同的声明(即“T&operator[]();”和“T operator[]()”)可以使用相同的代码段?

  •  0
  • John  · 技术社区  · 5 年前

    我知道他们之间的区别 T& operator[](); T operator[]()

    container[idx] 可以在return语句中为声明中的两种不同类型的返回类型使用。

    编译器如何实现这个目标(一个返回引用,另一个返回副本)?

    template<typename T>
    class Array
    {
     public:
     #ifdef RETURN_REFERENCE
        T& operator[](int idx)
     #else
        T  operator[](int idx)
     #endif
        {
             assert(idx<size);
             return container[idx];  // same expression works for T and T&
        }
     private:
        enum {size =100};
    
        T container[size];
    }
    
    0 回复  |  直到 5 年前
        1
  •  3
  •   Nicol Bolas    5 年前

    从根本上讲,这与本案没有什么不同:

    int i = <whatever>;
    int &j = i; //Reference
    int k = i; //Copy
    

    这个 i 表达不是孤立的。它是在特定的上下文中使用的,上下文的性质决定了表达式发生了什么。

    return 语句在返回值类型的上下文中执行。例如,如果返回的表达式与返回值的类型不同,编译器将尝试将表达式转换为适当的类型(非常类似于 float q = i; float ).

    表达式本身只是标识一个对象。被识别对象的情况取决于它的使用方式。如果用于初始化引用,则创建对该对象的引用。如果它用于初始化该类型的另一个对象,则会创建一个副本。