1

The following class should be used as an index into an ordinary array or std::vector. It basically helps with adress calculation for access into an array from a C interface.

class Index
{
    public:
        int data;

        inline void manipulate(Argument arg){
           // do some manipulation on data
        }

};

What is the right way to achieve an automatic conversion in order to use statements like:

Index myIndex;
...
a[myIndex] = A(...)
f(myIndex); // f is defined as f(int idx){...}

Side question: Will this class use exactly the storage for one int?

Michael
  • 7,407
  • 8
  • 41
  • 84
  • 1
    Have you read this - http://stackoverflow.com/questions/2143020/why-cant-i-inherit-from-int-in-c – ha9u63a7 Nov 17 '14 at 20:17
  • ["It's almost always a good idea to avoid writing automatic conversions"](http://www.gotw.ca/gotw/019.htm). See also [C++ Coding Standards](http://books.google.co.uk/books?id=mmjVIC6WolgC&lpg=PT256&ots=cdPrFOiFUd&dq=avoid%20providing%20implicit%20conversion%20c%2B%2B%20sutter&pg=PT256#v=onepage&q&f=false) – Chris Drew Nov 17 '14 at 20:25

2 Answers2

3

You can define an implicit conversion operator:

class Index
{
    int data;
public:
    // ...
    operator int() const { return data; }    
};

Side answer: Maybe.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • isn't that risky? i mean int() as operator? really :(? – ha9u63a7 Nov 17 '14 at 20:22
  • 1
    @hagubear: It's a terrible idea and very risky, but that's what you asked for. – Kerrek SB Nov 17 '14 at 20:27
  • 3
    @hagubear: When asked for the right way to shoot your daughter in the foot, would you rather I call child support or hand you the 12-gauge? Some questions have no right answer. – Kerrek SB Nov 17 '14 at 20:28
  • @hagubear relayed to Michael who asked :p – ha9u63a7 Nov 17 '14 at 20:28
  • Also +1 for the "Shooting my daughter in the foot" part – ha9u63a7 Nov 17 '14 at 20:29
  • Well, what would then be a good way to achieve what I want? ;-) – Michael Nov 17 '14 at 20:32
  • 1
    @Michael It would be a good idea to be *explicit*, say adding a function like `getData()` or `toInt()` – Red Alert Nov 17 '14 at 20:56
  • 1
    @Michael: I have no idea what you want -- quite possibly an XY problem? – Kerrek SB Nov 17 '14 at 22:20
  • @Kerrek SB: I want a class which helps me to compute an index (the X problem). Since the only member of this class is an `int` I implied that i could treat this class a _little bit_ like it was an actual int, with implicit conversion and so on (the Y problem). I see that this is not a very good idea, but would it be fine with what Red Alert proposed ("Make it explicit.") or are there other bad ideas in my concept? – Michael Nov 18 '14 at 10:59
  • @Michael: I think your XY is my X. Your *real* problem is accessing some data in some fashion, but we're not privy to that. It stands to reason that the solution you have decided is the right approach (namely an intermediate class that computes an index) is not at all the right approach. I can't tell, though, because I can't see the true Y. If you insist that your design is the right approach, then the implicit conversion is an acceptable solution. – Kerrek SB Nov 18 '14 at 11:01
  • @KerrekSB: I'm currently working with CUDA. I can not explain the whole design here, but my solution comes from hours and days of planning and thinking. I would not claim that I arrived at the best solution, but I arrived at a point where I realized that I simply can not strive for the absolutely best solution in any aspect. It would take forever. So the strategy is to implement a **good** solution and then improve it punctually where necessary. I'm not a native software engineer. – Michael Nov 18 '14 at 11:33
0

Choose between pest and cholera:

// Explicit Constructor
struct FirstIndex
{
    int data;
    explicit FirstIndex(const int& data)
    :   data(data)
    {}

    operator const int& () const { return data; }
    operator int& () { return data; }
};
bool operator == (const FirstIndex& a, const FirstIndex& b) { return a.data == b.data; }

// Explicit Conversion
struct SecondIndex
{
    int data;
    SecondIndex(const int& data)
    :   data(data)
    {}

    explicit operator const int& () const { return data; }
    explicit operator int& () { return data; }
};
bool operator == (const SecondIndex& a, const SecondIndex& b) { return a.data == b.data; }

// Nothing Explicit
struct ThirdIndex
{
    int data;
    ThirdIndex(const int& data)
    :   data(data)
    {}

    operator const int& () const { return data; }
    operator int& () { return data; }
};
bool operator == (const ThirdIndex& a, const ThirdIndex& b) { return a.data == b.data; }

int main()
{
    FirstIndex first(0);
    int first_result = 0;
    first += 1;
    // no match for ‘operator=’
    // first = first + 1;
    first_result = first;
    first_result == first;

    SecondIndex second(0);
    int second_result = 0;
    // error: no match for ‘operator+=’
    // second += 1;
    // no match for ‘operator+’
    // second = second + 1;
    // cannot convert ‘SecondIndex’ to ‘int’
    // second_result = second;
    second_result == second;

    ThirdIndex third(0);
    int third_result = 0;
    third += 1;
    third = third + 1;
    third_result = third;
    // This one is significant
    // error: ambiguous overload for ‘operator==’
    // third_result == third;
}