Thread: Specialising a member function with a template template parameter

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    2

    Specialising a member function with a template template parameter

    Here is the guts of my problem...

    I dont seem to be able to use the template template parameters TT1, TT2 & TT3 to specialize my member function Container:: object(). Basically I want to use them in order to select the
    correct member variable index1_, index2_ and index3_ as this presents a nice Tag-style interface.

    Any Ideas?

    Code:
    template<class T> struct X{ /* omitted*/ };
    template<class T> struct Y{ /* omitted*/ };
    template<class T> struct Z{ /* omitted*/ };
    
    template < class T,
    template <typename> class TT1,
    template <typename> class TT2,
    template <typename> class TT3>
    struct Container
    {
     template <template <typename> class FTT> FTT<T> object();
    
     /* All functions fail to compile. Error is
     // error C3207: 'MyClass<T,TT1,TT2,TT3>:: object' :
     // invalid template argument for 'FTT', class template expected
     template <> TT1<T> object<TT1>() { return object1_;}
     template <> TT2<T> object<TT12>() { return object2_;}
     template <> TT3<T> object<TT13() { return object3_;}
     //*/
    
     //* Compiles but needs to use template template parameters for generality
     template <> X<T> object<X>() { return object1_;}
     template <> Y<T> object<Y>() { return object2_;}
     template <> Z<T> object<Z>() { return object3_;}
     //*/
    
     private:
    
     TT1<T> object1_;
     TT2<T> object2_;
     TT3<T> object3_;
    };
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
     Container<int, X, Y, Z> container;
     X<int> result1 = container.object<X>();
     Y<int> result2 = container.object<Y>();
     Z<int> result3 = container.object<Z>();
     return 0;
    }

  2. #2
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,130
    Templates are only syntactic sugar over preprocessor replacement. And replacing all your template code, the compiler would have to generate 3 functions named "object" differing by returntype only. This is not possible. Not even for a normal non-template class.

    btw: include your error message next time, people don't like guessing what your problem may be, when you already have a specific error report.
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    127
    It's wrong you explicit specialize like this, this is because TT1, TT2 and TT3 is same thing before you instantiate it. to fix this problem, you have to try other ways

    e.g.

    Code:
    template<typename _Target> int match(_Target**);
    template<typename _Target> char match(...);
    
    template<typename _T, typename _U>
    struct same_type
    {
    	enum{ value = sizeof(int) == sizeof(match<_T>((_U**)0))};
    };
    
    template<bool _Cond, typename _True, typename _False>
    struct _if
    {
    	typedef _True value_type;
    };
    
    template<typename _True, typename _False>
    struct _if<false, _True, _False>
    {
    	typedef _False value_type;
    };
    
    template<int ID>
    struct IntToType{ enum {value = ID}; };
    
    template < class T,
    template <typename> class TT1,
    template <typename> class TT2,
    template <typename> class TT3>
    struct Container
    {
    	typedef TT1<T> T1;
    	typedef TT2<T> T2;
    	typedef TT3<T> T3;
    
    	template <template <typename> class FTT>
    	FTT<T> object()
    	{
    		typedef FTT<T> type;
    
    	                                  
    		return __object<_if<same_type<T1, type>::value,
    									IntToType<1>,
    									typename _if<same_type<T2, type>::value,
    											IntToType<2>,
    											typename _if<same_type<T3, type>::value,
    												IntToType<3>,
    												IntToType<0>
    											>::value_type
    									>::value_type
    						>::value_type::value, FTT<T> >::get(*this);
    	}
     
    	template<int _ID, typename _T>
    	struct __object
    	{
    		static _T get(Container&){ return _T(); };        
    	};
     
    	template<typename _T>
    	struct __object<1, _T>
    	{
    		static TT1<T> get(Container& c){ return c.object1_; }        
    	};
     
    	template<typename _T>
    	struct __object<2, _T>
    	{
    		static TT2<T> get(Container& c){ return c.object2_; }        
    	};
    
    	template<typename _T>
    	struct __object<3, _T>
    	{
    		static TT3<T> get(Container& c){ return c.object3_; }       
    	};
    
    	private:
    
    	TT1<T> object1_;
    	TT2<T> object2_;
    	TT3<T> object3_;
    };
    
    
    template<class T> struct X{ /* omitted*/ };
    template<class T> struct Y{ /* omitted*/ };
    template<class T> struct Z{ /* omitted*/ };
    
    int main()
    {
    	Container<int, X, Y, Z> container;
    	X<int> result1 = container.object<X>();
    	Y<int> result2 = container.object<Y>();
    	Z<int> result3 = container.object<Z>();
    
    
        std::system("pause");
    }
    Nana C++ Library is a GUI framework that designed to be C++ style, cross-platform and easy-to-use.

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    2
    Thanks for your posts.

    JinHao that is *wonderful* code... )...

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quite good, except that it blatantly violates all the rules about identifiers.

    1) Globally scoped identifiers starting with an underscore ("_if). Not allowed. All such identifiers are reserved for the implementation.

    2) Identifiers of any scope starting with a double underscore ("__object") or an underscore followed by an upper case letter ("_Cond", "_True", ...). Not allowed. All such identifiers are reserved for the implementation. In particular, an implementation may define extension keywords (such as MS's __declspec) or macros by such names, and that would seriously ruin your day.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    127
    An identifier starting with a double underscore like __object is for a inner class, starting with an underscore followed by an upper case letter like _Cond is for template parameter.

    the rule is quite simple, maybe it is not your rule or other rules.
    Nana C++ Library is a GUI framework that designed to be C++ style, cross-platform and easy-to-use.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The rule is simple, yeah. But it violates the C++ standard. You're simply not allowed to use such identifiers. This is not a matter of taste.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    127
    please show me the details in c++ standard.

    C++ supports UCN, is it violates the "Standard" if a programmer does not write C++ in English or uses other rules we've never met??
    Nana C++ Library is a GUI framework that designed to be C++ style, cross-platform and easy-to-use.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by jinhao View Post
    please show me the details in c++ standard.
    From the C++ Standard (ISO/IEC 14882:2003) section 17.4.3.1.2 "Global names":
    Certain sets of names and function signatures are always reserved to the implementation:
    - Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
    - Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Aug 2003
    Posts
    127
    i m so sorry, i've never read C++03. it's a damn thing to let non-compliant code written before 2003 be compliant for old new standard. sigh...
    Nana C++ Library is a GUI framework that designed to be C++ style, cross-platform and easy-to-use.

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It is exactly the same in C++98, and in the final public draft.
    http://www.open-std.org/jtc1/sc22/open/n2356/

    The same clause also appears in the final public draft of C99, and I dare claim that C90 contains exactly the same. (But I have no document to confirm this.)

    So this thing has been invalid since just about forever (since pre-standard versions of C++ followed C conventions).
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function name as template parameter?
    By Angus in forum C++ Programming
    Replies: 3
    Last Post: 11-12-2008, 01:45 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. cannot start a parameter declaration
    By Dark Nemesis in forum C++ Programming
    Replies: 6
    Last Post: 09-23-2005, 02:09 PM
  4. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  5. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM