templates: A<B<C>,C>

Started by
10 comments, last by aboeing 20 years, 5 months ago
Hi, Im just wondering if there is some way to enforce that two template parameters are the same, so if you have A < B < C > , D >, is there some way to make sure C == D? eg:

class A {};
class B {};
template <typename AB> 
class X {};
template <typename AB>
class Y {};

template<typename X, typename AB> 
class Z:public X {
 Y<AB>* dosomething();
}

//inmain:

Z<Y<A>,A> variable_ok;
Z<Y<A>,B> variable_should_not_be_ok;
Im using VC6, and would like it to be a compile-time assertion if possible. Thanks. edit: fixed so " < "'s show up [edited by - aboeing on October 21, 2003 12:31:59 AM]
Advertisement
Probably not. Template arguments must be completely specified types; and once templated types are completely specified, their template arguments only exist as part of the type.

What are you trying to do here? There may be another way.

EDIT: waitasec. Do you want your A to be implementable with ANY B, or with a specific B?

How appropriate. You fight like a cow.

[edited by - sneftel on October 21, 2003 12:40:30 AM]
quote:Original post by Sneftel
EDIT: waitasec. Do you want your A to be implementable with ANY B, or with a specific B?

Uh, not sure what you mean here. A and B should have anything to do with each other. think of them as A1 and A2 if that makes it clearer..

The specific thing im trying to do is to make a pluggable factory, which has a specifyable selection mechanism. (so i can register lots of objects, and different factories will create different objects according to which one is most appropriate). but different selection mechanisms will require different registration data structures, and also each factoryobject will need a diferent ''register'' function according to which data structure is being used.

eg:
#define STATIC_CHECK(expr) {char unnamed[(expr) ? 1 : 0];} class DataStructure {public:	void Register(int x) {};	int x;};class ADifferentDataStructure {public:	void Register(char *sz) {}; 	char *sz;};template <typename DS>class SelectionPolicy {public:	void UpdateRegistry() {};	DS structure;};template <typename DS>class Object : public DS {};template <typename SP, typename DS>class Factory : public SP {public:	Object<DS>* CreateObject() {		//STATIC_CHECK( that DS and SP<DS> are the same somehow);		return new Object<DS>;	};};//inmain://this is okay:Factory<SelectionPolicy<DataStructure>,DataStructure> f;f.CreateObject();//this is evil:Factory<SelectionPolicy<ADifferentDataStructure>,DataStructure> f;f.CreateObject();


The simplest solution I can think of is just to make one big datastrucutre class and then only use the bits of it that i need for different selection policys, but then this isn''t as flexible as i would like it to be, plus lots more typeing to register functions. =/

Does this make sense?
Darnit, aboeing, quit making me goof off.

You can do it if you''re willing to encode the template parameter into B (here represented by Foo):

template<typename T1, typename T2>class TypeEqualityChecker;template<typename T>class TypeEqualityChecker<T, T>{};template<typename T>class Foo{public:    typedef T myArg;};template<typename T1, typename T2>class Bar{    TypeEqualityChecker<typename T1::myArg, T2> checker;};int main(){    Bar<Foo<int>, int> asdf; // fine    Bar<Foo<int>, double> jklsemicolon; // causes a funky error}


How appropriate. You fight like a cow.
quote:Original post by aboeing
Hi, Im just wondering if there is some way to enforce that two template parameters are the same,
so if you have A < B < C > , D >, is there some way to make sure C == D?

If you wish, you could always do the following, for example
template<template<typename X> class Y, typename Z>class A{...};

Where the template parameter Y takes a class with a single template parameter, which you can use in the template class as
Y<Z>



[edited by - dot on October 22, 2003 2:42:36 AM]
Darnit, aboeing, quit making me goof off.
heh Sorry But thanks for answering all my questions

That looks exactly like what I want, but im not sure how your code works, if you have time, could you explain it? or point me to a resource which will? Thanks!

this:
template
class TypeEqualityChecker;
template
class TypeEqualityChecker
{};
is what im not really understanding..(the second one basically)

re:dot:interesting, I will have to try it when I get home. (im not sure if VC6 supports that..)
Neither suggestion will work with MSVC6, as i suspected, VC6 does not support nested templates:
(error C2954: template definitions cannot nest)

and for Sneftel''s suggestiong I get (on the class TypeEqualityChecker {}; line) :

error C2989: ''TypeEqualityChecker'' : template class has already been defined as a non-template class

any other suggestions?
Oops, yeah. More importantly, VC6 also doesn''t do partial template instantiation, which is what my TypeEqualityChecker does (it only has a version of TypeEqualityChecker for any two equal template arguments; another combination would produce an error). Um..... I think you''re kind of SOL here. VC6''s templates are for crap.

How appropriate. You fight like a cow.
Haha, you can''t do much in the way of cool template stuff with VC6.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
You want compile time intrensics. You can find a boost implementation here. Under template metaprogramming->traits.

http://www.boost.org/

It will allow you to determine if 2 templated params are the same etc.. at compile time.

-ddn

This topic is closed to new replies.

Advertisement