Thread: operator overload error

  1. #1
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937

    operator overload error

    Compiler says no appropriate operator^ is defined. But there seems to be one defined...
    Code:
    error: no match for ‘operator^’ in ‘num ^ power::p(3u)’
    Code:
    #include <cassert>
    #include <cmath>
    
    namespace power
    {
    
    	struct mult_p
    	{
    		mult_p(unsigned int n_) : n(n_) {}
    		unsigned int n;
    	};
    	
    	struct p
    	{
    		p(unsigned int n_) : n(n_) {}
    		unsigned int n;
    		mult_p & operator *() { return mult_p(n); }
    	};
    }
    
    template<class T>
    T operator ^ (T & left, power::p & right)
    {
       if(!right.n) return T(1);
       T ret = left;
       for(unsigned int i = 1; i < right.n; ++i)
    	ret *= left;
       return ret;
    }
    
    template<class T>
    T operator * (T & left, power::mult_p & right)
    {
       if(!right.n) return T(1);
       T ret = left;
       for(unsigned int i = 1; i < right.n; ++i)
    	ret *= left;
       return ret;
    }
    
    int main()
    {
    	using namespace power;
    	int num = 23;
    	int x = std::pow(static_cast<double>(num),3);
    	int y = num**p(3); // == x
    	int z = num^p(3);  // == x
    	assert(x == y && x == z);
    }
    What am I missing?
    - Thanks
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  2. #2
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    i thought it was a unary funtion & lhs was assumed to be 'this'

  3. #3
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    What am I missing?
    O_o

    Much.

    Soma

    Code:
    #include <cassert>
    #include <cmath>
    
    namespace power
    {
    
    	struct mult_p
    	{
    		mult_p(unsigned int n_) : n(n_) {}
    		unsigned int n;
    	};
    	
    	struct p
    	{
    		p(unsigned int n_) : n(n_), x(n_) {}
    		unsigned int n;
    		mult_p x;
    		const mult_p & operator *() const { return(x); }
    	};
    }
    
    template<class T>
    T operator ^ (const T & left, const power::p & right)
    {
       if(!right.n) return T(1);
       T ret = left;
       for(unsigned int i = 1; i < right.n; ++i)
    	ret *= left;
       return ret;
    }
    
    template<class T>
    T operator * (const T & left, const power::mult_p & right)
    {
       if(!right.n) return T(1);
       T ret = left;
       for(unsigned int i = 1; i < right.n; ++i)
    	ret *= left;
       return ret;
    }
    
    int main()
    {
    	using namespace power;
    	int num = 23;
    	int x = std::pow(static_cast<double>(num),3);
    	int y = num**p(3); // == x
    	int z = num^p(3);  // == x
    	assert(x == y && x == z);
    }

  4. #4
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    I see. Thanks.

    And no, I don't plan on using this sort of thing. I was just playing with the language.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    And no, I don't plan on using this sort of thing. I was just playing with the language.
    Why?
    You need to fix some stuff, but so what?
    You need a more illustrative name, 'exponent' for a favorite, but so what?

    Using the power of operator overloading to increase the expressiveness of C++ is a "Good Thing (R)". Witness the mind-boggling genius, the master sorcery that is 'Boost::Spirit'.

    Soma

  6. #6
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    exponent makes me think of Exp(x) = e^x
    Anyway... seems like more trouble than it ever would be worth.
    Code:
    #include <cassert>
    #include <cmath>
    #include <iostream>
    
    namespace power
    {
    	struct mult_p
    	{
    		mult_p(unsigned int n_=0) : n(n_) {}
    		unsigned int n;
    	};
    	
    	struct p
    	{
    		p(unsigned int n_=0) : n(n_), x(n_) {}
    		unsigned int n;
    		mult_p x;
    		const mult_p & operator *() const { return x; }
    	};
    
    #define DECLARE_POWER(n) const p p##n(n)
    #define DP DECLARE_POWER
    DP(1); DP(2); DP(3); DP(4); DP(5); DP(6); DP(7); DP(8); DP(9); DP(10); DP(11); DP(12);
    DP(13);DP(14);DP(15);DP(16);DP(17);DP(18);DP(19);DP(20);DP(21);DP(22); DP(23); DP(24);
    #undef DP
    #undef DECLARE_POWER
    }//namespace power
    
    template<class T>
    T operator ^ (const T & left, const power::p & right)
    {
       if(!right.n) return T(1);
       T ret = left;
       for(unsigned int i = 1; i < right.n; ++i)
    	ret *= left;
       return ret;
    }
    
    template<class T>
    T operator * (const T & left, const power::mult_p & right)
    {
       if(!right.n) return T(1);
       T ret = left;
       for(unsigned int i = 1; i < right.n; ++i)
    	ret *= left;
       return ret;
    }
    
    int main()
    {
    	using namespace power;
    	int num = 23;
    	int x = std::pow(static_cast<double>(a),3);
    	int b = num**p3;
    	int c = num^p3;
    	int d = num**p(3);
    	int e = num^p(3);
    	std::cout << num << '\n'
    		  << x << '\n'
    		  << b << '\n'
    		  << c << '\n'
    		  << d << '\n'
    		  << e << std::endl;
    }
    The language just doesn't want to do it. It's too bad (in a superficial sense) that you can't define objects that function as operators. E++ will do the following:
    Code:
    template<class T>
    class operator ** : precedence ++
    {
       T operator binary(const T & l, const unsigned int r)
        {
            T ret = l;
            for(unsigned int i = 1; i < r; ++i)
                ret *= l;
            return ret;
        }
        void operator unary<arg_right>(const std::string & s)
        {
            std::cerr << "Urgent thing! " << s << std::endl;
        }
    };
    
    using operator **;
    int main()
    {
        std::cout << 2.334**7 << std::endl;
        **"This would be so cool!";
        unsigned int * ptr = new unsigned int(3);
        std::cout << (2**ptr) << std::endl; //This would not be so cool....
        //Well, as long as ptr wouldn't get cast into an unsigned int, we'd be ok.
    }
    Code:
    template <class T>
    class operator ^
    {
       T operator binary(T&l, const unsigned int r)
        { . . . . . }
    };
    
    int main()
    {
        using operator ^;
        std::cout << 2^10 << std::endl;
        operator ^ = default;
        std::cout << std::hex << 0^0xF1 << std::endl;
    }
    Mass confusion would ensue.
    Last edited by CodeMonkey; 01-25-2009 at 09:50 PM.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  7. #7
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    exponent makes me think of Exp(x) = e^x
    Anyway... seems like more trouble than it ever would be worth.
    that's an exponential not an exponent

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. An error is driving me nuts!
    By ulillillia in forum C Programming
    Replies: 5
    Last Post: 04-04-2009, 09:15 PM
  3. Making C DLL using MSVC++ 2005
    By chico1st in forum C Programming
    Replies: 26
    Last Post: 05-28-2008, 01:17 PM
  4. Connecting to a mysql server and querying problem
    By Diod in forum C++ Programming
    Replies: 8
    Last Post: 02-13-2006, 10:33 AM
  5. Couple C questions :)
    By Divx in forum C Programming
    Replies: 5
    Last Post: 01-28-2003, 01:10 AM