2014-09-23 17 views
2

我重载运营商的数据结构,所以我有标准的函数声明:运算符重载C++:只写版本

T & operator[](int i); //used for regular objects 
const T & operator[](int i) const; // used for const objects 

所以我想要做的是有运营商[双版本]用于常规对象:当使用operator []写入而不是读取时,会执行一些不同的操作。

我一直在阅读,这是可能的,但我还没有看到任何代码。

我见过很多次这个问题,我看过答案''operator [] const'版本用于阅读“ - >但这不是真的;它仅用于类的const实例化。

任何人都可以提供指导检测写事件触发不同的行为? 也许是复制构造函数中的技巧?

+5

AFAIK你可以在C做到这一点的唯一途径++是返回一个代理值。 – milleniumbug 2014-09-23 22:00:36

+0

在C++中重载操作符\ [\],但为了防止\ [i \] = one \ _special \ _specific \ _value](http://stackoverflow.com/questions/20105097/overloading-operator-in -c-but-to-prevent-ai-one-special-specific-value) – Deduplicator 2014-09-23 22:05:58

+0

或者这个:[Vector,proxy class和C++中的点运算符](https://stackoverflow.com/questions/7182963/vector-proxy -class-and-dot-operator-in-c) – Deduplicator 2014-09-23 22:06:47

回答

0

正如在评论中提到的一样,您需要返回一个代理,AKA智能引用,它是您想要的实际类型T的包装,并且链接到调用[]运算符的原始对象。

当代理位于=的左侧时,编译器将调用其赋值运算符来键入T. 当代理位于=的右侧时,编译器将调用其演算操作符来键入T.

这里是一个字符串例如,我想在斯科特Meyer的有效的C++ 描述主要的第一行应打印“写入字符串” 第二行将打印

struct String 
{ 
    char text[10]; 
    struct CharReference; // forward declare char proxy class 
    CharReference String::operator[] (int index); 
    void print() { printf("%s",text); } 
}; 




struct String::CharReference 
{ CharReference(String * s, int i) ; 
    operator char(); 
    const char & String::CharReference::operator = (const char & rhs) ; 
    int index; 
    String *theString; 
}; 

const char & String::CharReference::operator = (const char & rhs) 
{ 
    printf("Writing to the string\n"); 
    theString->text[index] = rhs; 
    return rhs; 
} 

String::CharReference::operator char() 
{ 
    printf("Reading from the string\n"); 
    return theString->text[index]; 
} 

String::CharReference::CharReference(String * s, int i):theString(s), index(i) {} 

String::CharReference String::operator[] (int index) 
{ 
    return CharReference(this, index); 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    String s; 
    s[0] = 'A'; 
    char c = s[0]; 
    return 0; 
} 
0
“从字符串读”

持有对象的类无法获取有关信息呃您对返回对象的访问权限是读取或写入权限。

只有对象本身有一些“我在哪个上下文中使用”的概念,通过成员函数限定符。

  • REF-预选赛
  • 常量/ volatile限定符

您可以在代理类使用。

#include <vector> 
#include <type_traits> 
#include <iostream> 

template <class T, class U = T, bool Constant = std::is_const<T>::value> 
class myproxy 
{ 
protected: 
    U& m_val; 
    myproxy& operator=(myproxy const&) = delete; 
public: 
    myproxy(U & value) : m_val(value) { } 
    operator T &() 
    { 
    std::cout << "Reading." << std::endl; 
    return m_val; 
    } 
}; 

template <class T> 
struct myproxy < T, T, false > : public myproxy<T const, T> 
{ 
    typedef myproxy<T const, T> base_t; 
public: 
    myproxy(T & value) : base_t(value) { } 
    myproxy& operator= (T const &rhs) 
    { 
    std::cout << "Writing." << std::endl; 
    this->m_val = rhs; 
    return *this; 
    } 
}; 

template<class T> 
struct mycontainer 
{ 
    std::vector<T> my_v; 
    myproxy<T> operator[] (typename std::vector<T>::size_type const i) 
    { 
    return myproxy<T>(my_v[i]); 
    } 
    myproxy<T const> operator[] (typename std::vector<T>::size_type const i) const 
    { 
    return myproxy<T const>(my_v[i]); 
    } 
}; 

int main() 
{ 
    mycontainer<double> test; 
    mycontainer<double> const & test2(test); 
    test.my_v.push_back(1.0); 
    test.my_v.push_back(2.0); 
    // possible, handled by "operator=" of proxy 
    test[0] = 2.0; 
    // possible, handled by "operator T const&()" of proxy 
    double x = test2[0]; 
    // Possible, handled by "operator=" of proxy 
    test[0] = test2[1]; 
} 

打印

Writing 
Reading 
Reading 
Writing