Thread: Ambiguous operator?

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Ambiguous operator?

    I'm getting an ambiguous operator error, and I'm not sure why.
    I've dumbed down the example. Can anyone spot the problem?

    Code:
    template<typename T, bool ReadOnly> class buffered_stream_iterator;
    
    template<typename T, bool ReadOnly, typename T2> T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs);
    
    template<typename T, bool ReadOnly>
    class buffered_stream_iterator:
    	public std::iterator<std::random_access_iterator_tag, T>
    {
    public:
    	template<typename ThisT, bool ReadOnly, typename T2> friend T2& operator += (T2& lhs, const buffered_stream_iterator<ThisT, ReadOnly>& rhs);
    };
    
    template<typename T, bool ReadOnly, typename T2> T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs)
    {
    	return lhs;
    }
    
    int main()
    {
    	buffered_stream_iterator<wchar_t, false> Test;
    	int n = 0;
    	n += Test;
    	return 0;
    }
    1>error C2593: 'operator +=' is ambiguous
    1> could be 'T2 &operator +=<ElemType_t,false,int>(T2 &,const buffered_stream_iterator<T,ReadOnly> &)' [found using argument-dependent lookup]
    1> with
    1> [
    1> T2=int,
    1> T=ElemType_t,
    1> ReadOnly=false
    1> ]
    1> or 'T2 &operator +=<ElemType_t,false,int>(T2 &,const buffered_stream_iterator<T,ReadOnly> &)'
    1> with
    1> [
    1> T2=int,
    1> T=ElemType_t,
    1> ReadOnly=false
    1> ]
    1> while trying to match the argument list '(int, buffered_stream_iterator<T,ReadOnly>)'
    1> with
    1> [
    1> T=ElemType_t,
    1> ReadOnly=false
    1> ]
    I'd appreciate any help.
    Last edited by Elysia; 07-22-2009 at 02:26 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    It compiles and runs fine in GCC once the errors are fixed due to BufType not being defined for the 2 structs that use it, and the template variables that are shadowed.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Okay... Now that you mention it, it does compile on VC10, but not on VC8.
    This is just plain weird... not to mention disturbing and problematic.
    Sorry about missing types and shadowed templates. I did compile it, but as always, VC8 doesn't always compile templates. And never complains about shadowed templates which I tend to forget. I updated the code sample anyway in case anyone else wants to have a look...

    I remember I haven't installed any service packs... let's see if SP1 helps.
    Last edited by Elysia; 07-22-2009 at 12:34 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    You've still got the shadowed parameters, Elysia. Should be something like:

    Code:
    	template<typename ThisT, bool ThisReadOnly, typename T2> 
    	friend T2& operator += (T2& lhs, const buffered_stream_iterator<ThisT, ThisReadOnly>& rhs);
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I know... I didn't fix it. But I fixed it now.
    But I am in a predicament here...
    VS8 doesn't compile the code.
    VS9 doesn't work - installation borked thanks to VS10 installer(s).
    VS10 is too slow to be a productive IDE...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> VS8 doesn't compile the code.

    Really? The updated code?

    >> VS9 doesn't work - installation borked thanks to VS10 installer(s).

    Yes, that can be pretty annoying.

    >> VS10 is too slow to be a productive IDE...

    Hmm, I've never tried it myself. Is it really that bad?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Sebastiani View Post
    Really? The updated code?
    The updated code doesn't work either...

    Yes, that can be pretty annoying.
    Ah, but here's something better.
    I figure the problem is with the dotCrapwork. But it requires 3.5 and since 3.5 is part of Win7, it's impossible to reinstall it. Great work, Microsoft.

    Hmm, I've never tried it myself. Is it really that bad?
    Performance is horrible. You should do yourself a favor and not try it.
    It starts super slow. It closes super slow.
    The live-compile compiles far too slow to be of any use (you keep getting errors way after they're gone and they appear way after you actually write the piece and the Error List gets cluttered with IntelliSense errors all the while).
    Not to mention it crashes often, and is just broken - it's not even possible to add Unit Tests for C++.
    Ah, and they removed the global path options in favor of unintelligible property sheets which are difficult to find and edit.
    It's not a beta. It's a pre-alpha.

    I think it will be a great product in the end, but right now, it's a bug fest.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> The updated code doesn't work either...

    Just curious, but does VS8 compile this?:

    Code:
    template<typename T, bool ReadOnly>
    class buffered_stream_iterator:
    	public std::iterator<std::random_access_iterator_tag, T>
    {
    public:
    	friend T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs);
    };
    >> Ah, but here's something better. I figure the problem is with the dotCrapwork. But it requires 3.5 and since 3.5 is part of Win7, it's impossible to reinstall it. Great work, Microsoft.

    Just a shot in the dark here, but perhaps you can uninstall VS10, make sure the registry doesn't have any VS9 remnants, and then reinstall VS9? Come to think of it, there's a slight chance that VS10 is actually running slow because of some botched values in the registry related to VS9. I've actually had that problem before with a Java installation.

    But yeah, that really sucks. Good luck - and if things don't work out you can always use GCC with the IDE of your choosing.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    It almost seems like the compiler is treating the forward-declaration of the template operator as an actual template definition. Have you tried removing that forward declaration, and moving the template definition to before the class definition?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Sebastiani View Post
    >> The updated code doesn't work either...

    Just curious, but does VS8 compile this?:

    Code:
    template<typename T, bool ReadOnly>
    class buffered_stream_iterator:
    	public std::iterator<std::random_access_iterator_tag, T>
    {
    public:
    	friend T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs);
    };
    How so? T2 isn't declared.
    Should I add a typename T2 in a template perhaps?

    Just a shot in the dark here, but perhaps you can uninstall VS10, make sure the registry doesn't have any VS9 remnants, and then reinstall VS9? Come to think of it, there's a slight chance that VS10 is actually running slow because of some botched values in the registry related to VS9. I've actually had that problem before with a Java installation.
    No... I've uninstalled VS10 and reinstall VS9 several times, but it refuses to work. I've also tried the Visual Studio Uninstaller tool to get rid of 9, but no go. I'm stuck until I reinstall Windows. Such a nice thing. Or stick with VS8 'til I can get VS10. Hopefully they'll provide Professional to students for free.

    But yeah, that really sucks. Good luck - and if things don't work out you can always use GCC with the IDE of your choosing.
    An interesting tidbit is that VS10 should work with any compiler. But I don't know easy that will be...
    But another IDE and compiler is probably out of the question. It would be a pain to get used to another one.
    Sigh. I'll have to think on that one.

    Quote Originally Posted by brewbuck View Post
    It almost seems like the compiler is treating the forward-declaration of the template operator as an actual template definition. Have you tried removing that forward declaration, and moving the template definition to before the class definition?
    No go with that either. The compiler still treats them as two different template definitions.

    Maybe I just have to write member wrappers that the operators call and make the operators inline. Thinking on that actually makes sense, since template friend non-class operators are usually a pain to add.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Should I add a typename T2 in a template perhaps?

    Whoops, sorry. Yes, that's what I meant.

    >> An interesting tidbit is that VS10 should work with any compiler. But I don't know easy that will be... But another IDE and compiler is probably out of the question. It would be a pain to get used to another one. Sigh. I'll have to think on that one.

    True. Well I wouldn't know what to recommend anyway, as I don't actually use an IDE and have never found one that I liked much. Besides that, I've heard VS *is* the best IDE out there from almost everyone, so you may not even be satisfied with what's available anyway. =/
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    (NOT A SOLUTION!)
    This code compiles:
    Code:
    #include <iterator>
    
    template<typename T, bool ReadOnly> class buffered_stream_iterator;
    
    template<typename T, bool ReadOnly, typename T2> T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs);
    
    template<typename T, bool ReadOnly>
    class buffered_stream_iterator:
    	public std::iterator<std::random_access_iterator_tag, T>
    {
    public:
    	template<typename T2> friend T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs);
    };
    
    template<typename T, bool ReadOnly, typename T2> T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs)
    {
    	return lhs;
    }
    
    int main()
    {
    	buffered_stream_iterator<wchar_t, false> Test;
    	int n = 0;
    	n += Test;
    	return 0;
    }
    It seems that the friend declaration in the class must not include extra template parameters. This is what is throwing the compiler off, thinking it's another operator. Using the parameters defined for the class works.
    Last edited by Elysia; 07-27-2009 at 02:43 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    That shouldn't work at all.

    What suite is compiling and linking this while honoring "friend"--allowing access to private members?

    Soma

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Ah yes, from one problem to the other. Template friends are just a pain; this solves the ambiguous operator, but fails to make the friend declaration work. Wonderful, that's what I call it.
    Good thing I decided to use an easier approach.

    I'm not even going to bother with this approach anymore >_<

    EDIT:
    Actually, this works!
    Code:
    #include <iterator>
    #include <iostream>
    
    template<typename T, bool ReadOnly> class buffered_stream_iterator;
    
    template<typename T, bool ReadOnly, typename T2> T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs);
    
    template<typename T, bool ReadOnly>
    class buffered_stream_iterator:
    	public std::iterator<std::random_access_iterator_tag, T>
    {
    public:
    	template<typename, bool, typename T2> friend T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs);
    
    private:
    	int m_Test;
    };
    
    template<typename T, bool ReadOnly, typename T2> T2& operator += (T2& lhs, const buffered_stream_iterator<T, ReadOnly>& rhs)
    {
    	std::cout << rhs.m_Test;
    	return lhs;
    }
    
    int main()
    {
    	buffered_stream_iterator<wchar_t, false> Test;
    	int n = 0;
    	n += Test;
    	return 0;
    }
    Last edited by Elysia; 07-27-2009 at 02:44 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  3. Stupid compiler errors
    By ChrisEacrett in forum C++ Programming
    Replies: 9
    Last Post: 11-30-2003, 05:44 PM
  4. Linking error
    By DockyD in forum C++ Programming
    Replies: 10
    Last Post: 01-20-2003, 05:27 AM
  5. <list>
    By Unregistered in forum C++ Programming
    Replies: 9
    Last Post: 02-24-2002, 04:07 PM