Code Fight
Code Fight

Reputation: 1

Error passing union as parameter in operator<<

I am trying to figure out an error in my trivial code below:

union YunYun
{   
    int i;

    YunYun() : i(99) {}

    friend std::ostream& operator<<(std::ostream &os, const YunYun &y)
    {   
        os << y.i;
        return os; 
    }   
};  

int main()
{
    YunYun yn;

    std::cout << yn << std::endl; //This will not execute.

    return 0;
}

If overloaded operator<< is a friend or a member function of my union, the compiler will give me an error, but if it's a normal function it works perfectly fine.

Any idea, what could have cause this error?

Upvotes: 0

Views: 68

Answers (1)

benf
benf

Reputation: 1005

I'm guessing this is failing for you in MS Visual C++?

Move the function definition out of the union:

union YunYun
{
    int i;

    YunYun() : i(99) {}

    friend std::ostream& operator<<(std::ostream& os, const YunYun& y);        
};

std::ostream& operator<<(std::ostream& os, const YunYun& y)
{
    os << y.i;
    return os;
}

int main()
{
    YunYun yn;

    std::cout<< yn <<std::endl; //This will not execute.

    return 0;
}

Even though the definition is outside of the union, the friend declaration inside the union causes operator<< to be a friend. It appears to be a bug in Visual C++ that causes this.

Looking a little further, it seems that there are some strange rules for exposing friend functions to the outside scope.

union YunYun
{
    int i;    
    YunYun() : i(99) {}

    friend std::ostream& operator<<(std::ostream& os, const YunYun& y)
    {
        os << y.i;        
        return os;
    }

    friend void foo()
    {
        std::cout << "foo" << std::endl;
    }

    friend void bar(const YunYun& y)
    {
        std::cout << "bar " << y.i << std::endl;
    }
};

// without something declared outside the union scope VC++ won't find this symbol
std::ostream& operator<<(std::ostream& os, const YunYun& y);

int main()
{
    YunYun yn;
    std::cout << yn << std::endl; //This will not execute in VC++ w/o declaration external to union scope
    // foo(); // error: undeclared identifier (in VC++/Clang/GCC)
    bar(yn); // works in all three compilers

    return 0;
}

Upvotes: 1

Related Questions