Thread: Specializing class

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

    Specializing class

    I'm having a hard time specializing a class.
    The template class takes these template parameters:
    Code:
    template
    <
    	typename Type,
    	typename Class,
    	typename ParamPolicy<Type>::Type (Class::* GetFunction)(),
    	void (Class::* SetFunction)(typename ParamPolicy<Type>::Type)
    >
    Now, I want to specialize the class so that it's possible to only supply the parameter for Type.
    Unfortunately, it's only possible to specialize the class, which means I have to supply arguments for the rest of the template parameters:
    Code:
    template<typename Type> class CUtilityMember<Type, Dummy, NULL, NULL>
    Of course, this isn't allowed (compile error).

    Another idea might be to put default arguments for Class, Get and Set (Dummy, NULL, NULL). However, I want to specialize the class to avoid memory overhead & stuff. So, I need a way to detect if Get and Set are NULL and if such case, perhaps derive from a special policy class.
    But I can't find a way to detect if Get and Set are NULL. Even though they are template parameters, expressions such as "Get == NULL" will only result in a non-constant expression compile error.
    Code:
    template<...> class CUtilityMember: private CCallbackPolicy<GetFunction == NULL && SetFunction == NULL>
    (Compile error: non-constant expression.)

    Another idea I thought of was to specialize CCallbackPolicy for when Get & Set == NULL, but then I'm in the same mess as the first problem. Something about cannot have a non-dependant type in a dependant type in specialization:
    Code:
    template<typename Type, typename Class> class CCallbackPolicy<Type, Class, NULL, NULL>
    (Error!)

    Does anyone know of a good way to actually accomplish this or am I once again asking for the impossible?
    Templates can be so ... unflexible. I just wish they would fix that!
    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
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I wish you would post a complete example that didn't depend on Boost.

    template<...> class CUtilityMember: private CCallbackPolicy<GetFunction == NULL && SetFunction == NULL>
    I don't use 'Boost' anymore, but from what I can recall: use 'Boost::MPL' meta-functions like 'equal_to' and 'and_' to yield 'true_type' or 'false_type' for which you can specialize a class template.

    Soma

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I could naturally post the complete code, but it does heavily rely on boost.
    Unfortunately, the code also is tatters and splinters since I haven't been able to piece it together.
    From what I see, equal_to & the like compare types (ie typename), but from what I remember, there are some ways to embed a value inside a boost template class (whatever it's called), but unfortunately, I do not remember HOW.

    But I can explain the general idea.
    CUtilityMember works by overloading operator = and operator Type.
    It takes the type, class type, get & set function pointers as template arguments.
    Operator = calls the set function, operator type calls the get function.
    The class must store a pointer to the class, as well.

    Now, I wish to be able to give the option to opt for "default behavior" for get/set and therefore, no need to supply get/set or class at all. This will eleminate the need for the memory overhead for storing the class pointer.
    And of course, operator = and operator type would behave differently.

    So I need to specialize the class or its behavior some way to get it right.
    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
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    It's really a completely different template, isn't it? Rather than force a happy marriage between what you have now and the so-called "default" behavior I recommend another template entirely.

    Remember that templates must be wholly defined at compile time to work. The reason you can't use NULL as a template parameter is because it's type doesn't match the function pointers' types at compile time. It's defined as a literal zero, and doesn't help the compiler discern the type of any instantiations of UtilityMembers.

    On the other hand, a full declaration of UtilityMember might have something like < int, foo, foo::getfoo, foo::setfoo > all of which have been declared and whose types are discernible at compile time. Therefore using the GetFunction parameter is exactly like calling or referencing foo::getfoo and the template is complete.

    What you would do instead might be something like the attached, but it's a lot of boilerplate and probably gets in the way, as opposed to something natural like a public variable or a real accessor function.
    Last edited by whiteflags; 09-27-2008 at 11:02 AM.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by citizen View Post
    It's really a completely different template, isn't it? Rather than force a happy marriage between what you have now and the so-called "default" behavior I recommend another template entirely.
    I don't know if I would call it an entirely different template...
    It's just supposed to be a specialized "CUtilityMember" for when you pass different template arguments, just like vector<bool> is different from the typical, say, vector<char>.

    Remember that templates must be wholly defined at compile time to work. The reason you can't use NULL as a template parameter is because it's type doesn't match the function pointers' types at compile time. It's defined as a literal zero, and doesn't help the compiler discern the type of any instantiations of UtilityMembers.
    I don't know. It doesn't make much sense, since the only type parameters are the first two, and they would be explicitly defined.
    Neither does it complain that 0 isn't a valid type or wrong type, but rather not a compile-time expression.

    What you would do instead might be something like the attached, but it's a lot of boilerplate and probably gets in the way, as opposed to something natural like a public variable or a real accessor function.
    Thanks, I'll have a look at it.
    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
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    >> It's just supposed to be a specialized "CUtilityMember" for when you pass different
    >> template arguments, just like vector<bool> is different from the typical, say,
    >> vector<char>.
    This is hardly the same concept. Your goal is to eliminate some template parameters. Specialization does not do this, and what you refer to as specialization is not specialization. vector <bool> being different from vector <char> has nothing to do with it. vector <bool> and vector <char> are different types altogether. It is precisely what you need.

    >> I don't know. It doesn't make much sense, since the only type parameters are the
    >> first two, and they would be explicitly defined.
    All template parameters are type parameters. By definition, function pointers refer to members by type only. If the type isn't available at compile time the template will not work. If a function pointer is NULL the assignment can be delayed until run-time.

    Ta-da.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    All template parameters are type parameters.
    Uh, no. There's also non-type template parameters, which are constant values of some type.
    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. Help with FIFO QUEUE
    By jackfraust in forum C++ Programming
    Replies: 23
    Last Post: 04-03-2009, 08:17 AM
  2. Class design problem
    By h3ro in forum C++ Programming
    Replies: 10
    Last Post: 12-19-2008, 09:10 AM
  3. Defining derivated class problem
    By mikahell in forum C++ Programming
    Replies: 9
    Last Post: 08-22-2007, 02:46 PM
  4. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM