Thread: true virtual templates

  1. #1
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708

    true virtual templates

    working on a project that relies heavily on Coplien's 'curiously recurring template' mechanism for compile-time polymorphism, I realized that all the while I had assumed that there was no way around having to tediously define each and every function in the base class (without some default action, as virtual functions can) - I was wrong!

    Code:
    #include <iostream>
    
    /* a hypothetical framework */
    
    template <class base_type>
    class abstract_interface
    {
    	public:
    	
    	inline
    	base_type &
    	base(void)
    	{
    		return static_cast<base_type&>(*this);
    	}
    	
    	inline
    	const base_type &
    	base(void) const
    	{
    		return static_cast<const base_type&>(*this);
    	}	
    	
    	template <class value_type>
    	inline
    	value_type
    	limit(value_type value)
    	{
    		return base().limit(value);
    	}
    	
    	template <class value_type>
    	inline
    	value_type
    	normalize(value_type value)
    	{
    		return base().normalize(value);
    	}
    };
    
    template <class base_type>
    class inherit_interface : public abstract_interface<base_type>
    {
    	public:
    	
    	template <class value_type>
    	inline
    	value_type
    	limit(value_type value)
    	{
    		std::cout << "limit [default]" << std::endl;
    		return value;
    	}
    	
    	template <class value_type>
    	inline
    	value_type
    	normalize(value_type value)
    	{
    		std::cout << "normalize [default]" << std::endl;
    		return value;
    	}
    };
    
    class object : public inherit_interface<object>
    {
    	public:
    	
    	template <class value_type>
    	inline
    	value_type
    	normalize(value_type value)
    	{
    		std::cout << "normalize [object]" << std::endl;
    		return value;
    	}
    };
    
    template <class base_type, class value_type>
    inline
    value_type
    normalize(abstract_interface<base_type> & lhs, value_type value)
    {
    	return lhs.normalize(value);
    }
    
    template <class base_type, class value_type>
    inline
    value_type
    limit(abstract_interface<base_type> & lhs, value_type value)
    {
    	return lhs.limit(value);
    }
    
    /* a simple test driver */
    
    int 
    main(void)
    {
    	object object;		
    	normalize(object, double());
    	limit(object, double());
    }
    abstract_interface binds the framework together, but inherit_interface transforms it into a truly 'virtual template'! I wonder if anyone else noticed this?
    Last edited by Sebastiani; 02-27-2006 at 01:30 AM. Reason: changed phrase 'run-time polymorphism' to 'compile-time polymorphism', syntax
    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;
    }

  2. #2
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    My compiler doesn't like your code. It also said "Up your nose with a rubber hose", which I just thought was uncalled for.

    Hehe... anyway, I couldn't compile you're hypothetical situation and I'm just simply not knowledgeable enough to run through it in my mind without making some mistake somewhere down the line. But given how amazed you are at this and the fact that I probably wouldn't have noticed, I guess I'll say...

    Wowzers! I can believe inherited_interface transforms it into a truly 'virtual template'! I never would have noticed!
    Sent from my iPadŽ

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    what errors are you getting?
    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;
    }

  4. #4
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Code:
    expected unqualified-id before "template"
    on every instance where template appears inside a class like on the functions. Also I'm getting a dozen or so errors in main which I'm sure are due to the template problem in the classes.
    Sent from my iPadŽ

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    try removing all of the 'inline' keywords - some compilers might not like the fact that I put it before 'template'?
    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;
    }

  6. #6
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Yep, that seemed to fix those. I'm still getting a few errors with your normalize() and limit() functions, though.

    Code:
    93 C:\...\Untitled1.cpp invalid initialization of non-const reference of type 'abstract_interface<object>&' from a temporary of type 'object' 
    77 C:\...\Untitled1.cpp in passing argument 1 of `value_type normalize(abstract_interface<base_type>&, value_type) [with base_type = object, value_type = double]' 
    94 C:\...\Untitled1.cpp invalid initialization of non-const reference of type 'abstract_interface<object>&' from a temporary of type 'object' 
    84 C:\...\Untitled1.cpp in passing argument 1 of `value_type limit(abstract_interface<base_type>&, value_type) [with base_type = object, value_type = double]'

    ...and knocking out the address of operator in the first arguement of both fixes that, but I don't know if doing that defeats the purpose of your question.
    Sent from my iPadŽ

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I edited two more lines above - does it compile?
    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;
    }

  8. #8
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Not for me. Same four errors.
    Sent from my iPadŽ

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    is that with

    Code:
    return lhs.base().normalize(value);
    ...or...

    Code:
    return lhs.normalize(value);
    ...or both?

    [edit]
    I really should have tested this on more than one compiler before posting - bleh!
    [/edit]
    Last edited by Sebastiani; 02-27-2006 at 01:16 AM.
    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;
    }

  10. #10
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Looks like just the first one. But as I said, it doesn't like the arguements, it seems, not the return.

    I use my own OS and my own compiler so there is no way you could have tested on this. Basically, I write the code in notepad, then I print it out, show it to my dog, and he barks the results of the compilation. As I said, though... Scruffy doesn't like those four lines.
    Last edited by SlyMaelstrom; 02-27-2006 at 01:19 AM.
    Sent from my iPadŽ

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    ah, right. I'll look into that some more. thanks for testing it out.

    I use my own OS and my own compiler so there is no way you could have tested on this. Basically, I write the code in notepad, then I print it out, show it to my dog, and he barks the results of the compilation. As I said, though... Scruffy doesn't like those four lines.
    great sense of humor, man.
    Last edited by Sebastiani; 02-27-2006 at 01:22 AM.
    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
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    ...it was the temporary in main - fixed. thanks again, Sly.
    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;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Forced moves trouble!!
    By Zishaan in forum Game Programming
    Replies: 0
    Last Post: 03-27-2007, 06:57 PM
  2. Questions about Templates
    By Shamino in forum C++ Programming
    Replies: 4
    Last Post: 12-18-2005, 12:22 AM
  3. opengl program as win API menu item
    By SAMSAM in forum Game Programming
    Replies: 1
    Last Post: 03-03-2003, 07:48 PM
  4. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM