views:

147

answers:

5

when I tried to compile the code: (note: func and func2 is not typo)

struct S
{
    void func2() {}
};

class O
{
public:
    inline S* operator->() const;
private:
    S* ses;
};

inline S* O::operator->() const
{
    return ses;
}

int main()
{
    O object;
    object->func();
    return 0;
}

there is a compile error reported:

D:\code>g++ operatorp.cpp -S -o operatorp.exe
operatorp.cpp: In function `int main()':
operatorp.cpp:27: error: 'struct S' has no member named 'func'

it seems that invoke the overloaded function of "operator->" is done during compile time? I'd added "-S" option for compile only.

+10  A: 

Yes, it's treated like an ordinary function call, it's just called by an overloaded operator. The compiler checks everything is valid at compile time. C++ is not like dynamic languages where it waits until runtime to work out if p->mynonexistantfunction() is a valid name for a function or not, the compiler will reject the code at compile time if the function name does not exist.

In this case it looks like a typo, S has a function func2() but your code calls func().

AshleysBrain
AshleysBrain: i mean to define a different function name. thanks, i should have used better names.
Allopen
+2  A: 

Yes, the compiler checks operators by it's result as any other function.

In this case if you had, for example,

S* foo() { ... }

(foo())->func();

the result would be the same.

Kotti
+3  A: 

In struct S you declared func2(), but in main,you try to call func().

try int main() { O object; object->func2(); return 0; }

Biber
+1  A: 

In C++ language you cannot select a class member by name at run-time. Class member selection (by immediate member name) is always done at compile-time. There's no way around it.

If you want to implement member selection at run-time, the only thing you can use is operators .* and ->* (the former - non overloadable). However, these operators in their built-in form expect pointers-to-members as their right-hand operands. If you want to select something by name (as a string) you can overload ->* to make it take a different argument type, but in any case you'll have to implement the mapping from string to actual member manually. However, for member functions (as opposed to data members) this is usually pretty tricky.

AndreyT
A: 

object->func() is just syntactic sugar for object->operator->()->func() for user-defined types. Since O::operator->() yields an S*, this requires the existence of the method S::func() at compile time.

FredOverflow