views:

205

answers:

4

What do i have to do to this code to make it compile, it's braking around this line:

auto val = what.getObject();

#include<iostream>
using namespace std;

class CUP{
    public:
        void whatsHappening(){}
};

class MUG{
    public:
        void whatsHappening(){}
};

class CupThrower{
    public:
        CUP cp;
        CUP getObject(){ return cp;}
};

class MugThrower{
    public:
        MUG mg;
        MUG getObject(){return mg;}
};

template <typename T> void whatsHappening(T what){

    auto val = what.getObject(); //DOES NOT COMPILE
    val.whatsHappening();
}

int main(){
    CupThrower ct;
    MugThrower mt;
    whatsHappening(ct);
    whatsHappening(mt);
    return 0;
}

i am using VS2008 to compile.

+3  A: 

Auto is a feature only present in C++0x and, therefore, isn't enabled by default in most (if not all) the compilers. Have you used the appropriate options in your compiler to enable it?

cake
i am using visual studio 2008 to compile, what do i have to enable to make this work?
LoudNPossiblyRight
@Loud: You have to enable "upgrade to Visual Studio 2010" :-)
James McNellis
actually, no. Auto is available in the C standard (and thus I'm pretty sure C++) The only thing is that it does absolutely nothing. It defines a local variable as having local scope... um... yay?
Brian Postow
@Brian: Since the `auto` in its original form keyword hasn't been seen in the wild for decades, the next C++ standard has redefined its meaning.
sbi
A: 

It doesn't compile because you're trying to deal with zero-sized non-function objects.

Edit: Works fine for me in VS2010.

DeadMG
i'm not too sure what you mean by this.
LoudNPossiblyRight
Neither am I, but I'm pretty sure this isn't the reason why your code isn't compiling.
John Dibling
DeadMG makes this kind of stuff up as he goes along - ignore.
anon
@John, it isn't the reason at all. Heck, it's not even possible to have a zero-sized object in standard C++.
iconiK
One of us at least attempted to post a useful suggestion. One of us just trolled.
DeadMG
+10  A: 

Auto isn't supported in VS2008. Use VS2010 and later versions, or another compiler supporting this feature.

Klaim
It was the compile version, i dont have vs2010 but i tried with gcc 4.4* and it worked. thanks for the tip.
LoudNPossiblyRight
+3  A: 

Others have said that auto isn't in VC9, which is sort-of true. auto doesn't mean in the current C++ Standard what it means in C++0x. In the current Standard, it effectively means nothing useful. Long story short, you can't use auto the way you're trying to use it here.

But there is an alternative. In this code:

template <typename T> void whatsHappening(T what){

    auto val = what.getObject(); //DOES NOT COMPILE
    val.whatsHappening();
}

...the problem you're having is val is of an unknown type. If T is CupThrower, then getObject() returns a CUP. Likewise, for MugThrower, getObject() returns a MUG. The way your code is written, you have no way to know the type returned by getObject() based solely on the type of T. So the solution is to add a way to know it. Try this:

class CupThrower{
    public:
        typedef CUP ObjectType;
        ObjectType cp;
        ObjectType getObject(){ return cp;}
};

class MugThrower{
    public:
        typedef MUG ObjectType;
        ObjectType mg;
        ObjectType getObject(){return mg;}
};

Now the type returned by getObject() is part of the enclosing class. You can change your whatsHappening() function to use this information:

template <typename T> void whatsHappening(T what){

    T::ObjectType val = what.getObject(); //DOES COMPILE!
    val.whatsHappening();
}

And all is right with the world again.

John Dibling
that's well and good but i'm trying to learn how to use implicitly typed variables with c++0x, this doesnt answer my question.
LoudNPossiblyRight
Then remove the C++ tag.
John Dibling
You need to change that to `typename T::ObjectType val = ...`
R Samuel Klatchko