Connecting Tech Pros Worldwide Forums | Help | Site Map

template specialization

Alexander Stippler
Guest
 
Posts: n/a
#1: Jul 22 '05
Hi,

what do I have to do to get this (incorrect) piece of code to work. The
specialization is wrong, but how can I do it?

template <typename T, typename V>
class Mask
{
public:
Mask(int i) {}
};

enum DefaultValues
{
ZeroDefault,
NaNDefault,
WhateverDefault
};

template <typename T, typename I, DefaultValues D>
struct DefaultElement
{
static const T value;
};

template <typename T, typename I, DefaultValues D>
const T
DefaultElement<T, I, D>::value = T();

// how to write the following correctly????
template <typename T, typename V>
const T DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);


Best regards,
alex

Alexander Stippler
Guest
 
Posts: n/a
#2: Jul 22 '05

re: template specialization


Alexander Stippler wrote:
[color=blue]
> Hi,
>
> what do I have to do to get this (incorrect) piece of code to work. The
> specialization is wrong, but how can I do it?
>
> template <typename T, typename V>
> class Mask
> {
> public:
> Mask(int i) {}
> };
>
> enum DefaultValues
> {
> ZeroDefault,
> NaNDefault,
> WhateverDefault
> };
>
> template <typename T, typename I, DefaultValues D>
> struct DefaultElement
> {
> static const T value;
> };
>
> template <typename T, typename I, DefaultValues D>
> const T
> DefaultElement<T, I, D>::value = T();[/color]

sorry for the incorrect incorrect code ;-). The type of the const value must
be Mask<T, V>!
[color=blue]
> // how to write the following correctly????
> template <typename T, typename V>
> const T
> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T,V>(1);[/color]

Thus:

template <typename T, typename V>
const Mask<T, V>
DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);

But what's wrong with it?
John Harrison
Guest
 
Posts: n/a
#3: Jul 22 '05

re: template specialization


On Mon, 19 Jul 2004 21:38:17 +0200, Alexander Stippler
<stip@mathematik.uni-ulm.de> wrote:
[color=blue]
> Alexander Stippler wrote:
>[color=green]
>> Hi,
>>
>> what do I have to do to get this (incorrect) piece of code to work. The
>> specialization is wrong, but how can I do it?
>>
>> template <typename T, typename V>
>> class Mask
>> {
>> public:
>> Mask(int i) {}
>> };
>>
>> enum DefaultValues
>> {
>> ZeroDefault,
>> NaNDefault,
>> WhateverDefault
>> };
>>
>> template <typename T, typename I, DefaultValues D>
>> struct DefaultElement
>> {
>> static const T value;
>> };
>>
>> template <typename T, typename I, DefaultValues D>
>> const T
>> DefaultElement<T, I, D>::value = T();[/color]
>
> sorry for the incorrect incorrect code ;-). The type of the const value
> must
> be Mask<T, V>!
>[color=green]
>> // how to write the following correctly????
>> template <typename T, typename V>
>> const T
>> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T,V>(1);[/color]
>
> Thus:
>
> template <typename T, typename V>
> const Mask<T, V>
> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>
> But what's wrong with it?[/color]

I think you are forgetting to specialise the actual template and just
writing the code for the static value. Try this


template <typename T, typename V>
struct DefaultElement<Mask<T, V>, T, ZeroDefault>
{
static const Mask<T, V> value;
};

template <typename T, typename V>
const Mask<T, V>
DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);

john
Victor Bazarov
Guest
 
Posts: n/a
#4: Jul 22 '05

re: template specialization


Alexander Stippler wrote:[color=blue]
> Alexander Stippler wrote:
>
>[color=green]
>>Hi,
>>
>>what do I have to do to get this (incorrect) piece of code to work. The
>>specialization is wrong, but how can I do it?
>>
>>template <typename T, typename V>
>>class Mask
>>{
>> public:
>> Mask(int i) {}
>>};
>>
>>enum DefaultValues
>>{
>> ZeroDefault,
>> NaNDefault,
>> WhateverDefault
>>};
>>
>>template <typename T, typename I, DefaultValues D>
>>struct DefaultElement
>>{
>> static const T value;
>>};
>>
>>template <typename T, typename I, DefaultValues D>
>>const T
>>DefaultElement<T, I, D>::value = T();[/color]
>
>
> sorry for the incorrect incorrect code ;-). The type of the const value must
> be Mask<T, V>!
>
>[color=green]
>>// how to write the following correctly????
>>template <typename T, typename V>
>>const T
>>DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T,V>(1);[/color]
>
>
> Thus:
>
> template <typename T, typename V>
> const Mask<T, V>
> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>
> But what's wrong with it?[/color]

Wrong? You're trying to _partially_ specialize a member without first
partially specializing the class itself.

Victor
Alexander Stippler
Guest
 
Posts: n/a
#5: Jul 22 '05

re: template specialization


Victor Bazarov wrote:
[color=blue]
> Alexander Stippler wrote:[/color]
...
[color=blue][color=green]
>> Thus:
>>
>> template <typename T, typename V>
>> const Mask<T, V>
>> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>
>> But what's wrong with it?[/color]
>
> Wrong? You're trying to _partially_ specialize a member without first
> partially specializing the class itself.
>
> Victor[/color]


Yes, but how to do it:

template <typename T, typename V>
struct DefaultElement<Mask<T, V>, T, ZeroDefault>
{
static const Mask<T, V> value;
};

This does not solve the problem. Inserting it into the code results in
'template argument list must match the parameter list'.

regards,
Alex

John Harrison
Guest
 
Posts: n/a
#6: Jul 22 '05

re: template specialization


On Mon, 19 Jul 2004 22:00:23 +0200, Alexander Stippler
<stip@mathematik.uni-ulm.de> wrote:
[color=blue]
> Victor Bazarov wrote:
>[color=green]
>> Alexander Stippler wrote:[/color]
> ...
>[color=green][color=darkred]
>>> Thus:
>>>
>>> template <typename T, typename V>
>>> const Mask<T, V>
>>> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>>
>>> But what's wrong with it?[/color]
>>
>> Wrong? You're trying to _partially_ specialize a member without first
>> partially specializing the class itself.
>>
>> Victor[/color]
>
>
> Yes, but how to do it:
>
> template <typename T, typename V>
> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
> {
> static const Mask<T, V> value;
> };
>
> This does not solve the problem. Inserting it into the code results in
> 'template argument list must match the parameter list'.
>
> regards,
> Alex
>[/color]

Then I think you have a broken compiler. That compiles on the two
compilers I tried it on (gcc 3.3.1 and VC++ 7.1).

john
Alexander Stippler
Guest
 
Posts: n/a
#7: Jul 22 '05

re: template specialization


John Harrison wrote:[color=blue]
>
> Then I think you have a broken compiler. That compiles on the two
> compilers I tried it on (gcc 3.3.1 and VC++ 7.1).
>
> john[/color]

Yes, now I think so, too. It compiles fine with Intel's icc, but the broken
compiler I tried to use was gcc 3.4 !!!! Seems like a regression!
Victor Bazarov
Guest
 
Posts: n/a
#8: Jul 22 '05

re: template specialization


John Harrison wrote:[color=blue]
> On Mon, 19 Jul 2004 22:00:23 +0200, Alexander Stippler
> <stip@mathematik.uni-ulm.de> wrote:
>[color=green]
>> Victor Bazarov wrote:
>>[color=darkred]
>>> Alexander Stippler wrote:[/color]
>>
>> ...
>>[color=darkred]
>>>> Thus:
>>>>
>>>> template <typename T, typename V>
>>>> const Mask<T, V>
>>>> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>>>
>>>> But what's wrong with it?
>>>
>>>
>>> Wrong? You're trying to _partially_ specialize a member without first
>>> partially specializing the class itself.
>>>
>>> Victor[/color]
>>
>>
>>
>> Yes, but how to do it:
>>
>> template <typename T, typename V>
>> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>> {
>> static const Mask<T, V> value;
>> };
>>
>> This does not solve the problem. Inserting it into the code results in
>> 'template argument list must match the parameter list'.
>>
>> regards,
>> Alex
>>[/color]
>
> Then I think you have a broken compiler. That compiles on the two
> compilers I tried it on (gcc 3.3.1 and VC++ 7.1).[/color]

It does? Could you please post your version that compiles? Here is
my attempt:
------------------------------------------------------------
template <typename T, typename V>
class Mask
{
public:
int i;
Mask(int i) {}
};

enum DefaultValues
{
ZeroDefault,
NaNDefault,
WhateverDefault
};

template<typename T, typename I, DefaultValues D>
struct DefaultElement
{
static const T value;
};

template<typename T, typename V>
struct DefaultElement<Mask<T, V>, T, ZeroDefault>
{
static const Mask<T,V> value;
};

int main()
{
DefaultElement<double, char> dedc; // **************
return dedc.value.i;
}
------------------------------------------------------------
VC++ complains at the line marked with ***** saying "too few template
arguments". Have you actually attempted to instantiate DefaultElement?

V
Victor Bazarov
Guest
 
Posts: n/a
#9: Jul 22 '05

re: template specialization


Victor Bazarov wrote:[color=blue]
> John Harrison wrote:
>[color=green]
>> On Mon, 19 Jul 2004 22:00:23 +0200, Alexander Stippler
>> <stip@mathematik.uni-ulm.de> wrote:
>>[color=darkred]
>>> Victor Bazarov wrote:
>>>
>>>> Alexander Stippler wrote:
>>>
>>>
>>> ...
>>>
>>>>> Thus:
>>>>>
>>>>> template <typename T, typename V>
>>>>> const Mask<T, V>
>>>>> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>>>>
>>>>> But what's wrong with it?
>>>>
>>>>
>>>>
>>>> Wrong? You're trying to _partially_ specialize a member without first
>>>> partially specializing the class itself.
>>>>
>>>> Victor
>>>
>>>
>>>
>>>
>>> Yes, but how to do it:
>>>
>>> template <typename T, typename V>
>>> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>>> {
>>> static const Mask<T, V> value;
>>> };
>>>
>>> This does not solve the problem. Inserting it into the code results in
>>> 'template argument list must match the parameter list'.
>>>
>>> regards,
>>> Alex
>>>[/color]
>>
>> Then I think you have a broken compiler. That compiles on the two
>> compilers I tried it on (gcc 3.3.1 and VC++ 7.1).[/color]
>
>
> It does? Could you please post your version that compiles? Here is
> my attempt:
> ------------------------------------------------------------
> template <typename T, typename V>
> class Mask
> {
> public:
> int i;
> Mask(int i) {}
> };
>
> enum DefaultValues
> {
> ZeroDefault,
> NaNDefault,
> WhateverDefault
> };
>
> template<typename T, typename I, DefaultValues D>
> struct DefaultElement
> {
> static const T value;
> };
>
> template<typename T, typename V>
> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
> {
> static const Mask<T,V> value;
> };
>
> int main()
> {
> DefaultElement<double, char> dedc; // **************
> return dedc.value.i;
> }
> ------------------------------------------------------------
> VC++ complains at the line marked with ***** saying "too few template
> arguments". Have you actually attempted to instantiate DefaultElement?
>[/color]

--------------------------------------------------- This works with VC++
Note that 'DefaultElement' is not specialised based on Mask<T,V> and T,
but instead on T,V, and ZeroDefault.
------------------------------------------------------------------------
template <typename T, typename V>
class Mask
{
public:
int i;
Mask(int i) : i(i) {}
};

enum DefaultValues
{
ZeroDefault,
NaNDefault,
WhateverDefault
};

template<typename T, typename I, DefaultValues D>
struct DefaultElement
{
static const T value;
};

template<typename T, typename V>
struct DefaultElement<T,V,ZeroDefault>
{
static const Mask<T,V> value;
};

template<typename T, typename V>
const Mask<T,V> DefaultElement<T,V,ZeroDefault>::value(42);

int main()
{
DefaultElement<double,char,ZeroDefault> dedc;
return dedc.value.i;
}
Alexander Stippler
Guest
 
Posts: n/a
#10: Jul 22 '05

re: template specialization


Victor Bazarov wrote:
[color=blue]
> Victor Bazarov wrote:[color=green]
>> John Harrison wrote:
>>[color=darkred]
>>> On Mon, 19 Jul 2004 22:00:23 +0200, Alexander Stippler
>>> <stip@mathematik.uni-ulm.de> wrote:
>>>
>>>> Victor Bazarov wrote:
>>>>
>>>>> Alexander Stippler wrote:
>>>>
>>>>
>>>> ...
>>>>
>>>>>> Thus:
>>>>>>
>>>>>> template <typename T, typename V>
>>>>>> const Mask<T, V>
>>>>>> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>>>>>
>>>>>> But what's wrong with it?
>>>>>
>>>>>
>>>>>
>>>>> Wrong? You're trying to _partially_ specialize a member without first
>>>>> partially specializing the class itself.
>>>>>
>>>>> Victor
>>>>
>>>>
>>>>
>>>>
>>>> Yes, but how to do it:
>>>>
>>>> template <typename T, typename V>
>>>> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>>>> {
>>>> static const Mask<T, V> value;
>>>> };
>>>>
>>>> This does not solve the problem. Inserting it into the code results in
>>>> 'template argument list must match the parameter list'.
>>>>
>>>> regards,
>>>> Alex
>>>>
>>>
>>> Then I think you have a broken compiler. That compiles on the two
>>> compilers I tried it on (gcc 3.3.1 and VC++ 7.1).[/color]
>>
>>
>> It does? Could you please post your version that compiles? Here is
>> my attempt:
>> ------------------------------------------------------------
>> template <typename T, typename V>
>> class Mask
>> {
>> public:
>> int i;
>> Mask(int i) {}
>> };
>>
>> enum DefaultValues
>> {
>> ZeroDefault,
>> NaNDefault,
>> WhateverDefault
>> };
>>
>> template<typename T, typename I, DefaultValues D>
>> struct DefaultElement
>> {
>> static const T value;
>> };
>>
>> template<typename T, typename V>
>> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>> {
>> static const Mask<T,V> value;
>> };
>>
>> int main()
>> {
>> DefaultElement<double, char> dedc; // **************
>> return dedc.value.i;
>> }
>> ------------------------------------------------------------
>> VC++ complains at the line marked with ***** saying "too few template
>> arguments". Have you actually attempted to instantiate DefaultElement?
>>[/color]
>
> --------------------------------------------------- This works with VC++
> Note that 'DefaultElement' is not specialised based on Mask<T,V> and T,
> but instead on T,V, and ZeroDefault.
> ------------------------------------------------------------------------
> template <typename T, typename V>
> class Mask
> {
> public:
> int i;
> Mask(int i) : i(i) {}
> };
>
> enum DefaultValues
> {
> ZeroDefault,
> NaNDefault,
> WhateverDefault
> };
>
> template<typename T, typename I, DefaultValues D>
> struct DefaultElement
> {
> static const T value;
> };
>
> template<typename T, typename V>
> struct DefaultElement<T,V,ZeroDefault>
> {
> static const Mask<T,V> value;
> };
>
> template<typename T, typename V>
> const Mask<T,V> DefaultElement<T,V,ZeroDefault>::value(42);
>
> int main()
> {
> DefaultElement<double,char,ZeroDefault> dedc;
> return dedc.value.i;
> }[/color]

Are you sure? The general version has template parameter T and defines a
constant of type T. The specialization uses Mask<T,V> as the former T and
ZeroDefault as specialization of D. So if type Mask<T, V> replaced type T
why isn't it
DefaultElement<Mask<T,V>, T, ZeroDefault>
?

Alex
Alexander Stippler
Guest
 
Posts: n/a
#11: Jul 22 '05

re: template specialization


Victor Bazarov wrote:
[color=blue]
> Victor Bazarov wrote:[color=green]
>> John Harrison wrote:
>>[color=darkred]
>>> On Mon, 19 Jul 2004 22:00:23 +0200, Alexander Stippler
>>> <stip@mathematik.uni-ulm.de> wrote:
>>>
>>>> Victor Bazarov wrote:
>>>>
>>>>> Alexander Stippler wrote:
>>>>
>>>>
>>>> ...
>>>>
>>>>>> Thus:
>>>>>>
>>>>>> template <typename T, typename V>
>>>>>> const Mask<T, V>
>>>>>> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>>>>>
>>>>>> But what's wrong with it?
>>>>>
>>>>>
>>>>>
>>>>> Wrong? You're trying to _partially_ specialize a member without first
>>>>> partially specializing the class itself.
>>>>>
>>>>> Victor
>>>>
>>>>
>>>>
>>>>
>>>> Yes, but how to do it:
>>>>
>>>> template <typename T, typename V>
>>>> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>>>> {
>>>> static const Mask<T, V> value;
>>>> };
>>>>
>>>> This does not solve the problem. Inserting it into the code results in
>>>> 'template argument list must match the parameter list'.
>>>>
>>>> regards,
>>>> Alex
>>>>
>>>
>>> Then I think you have a broken compiler. That compiles on the two
>>> compilers I tried it on (gcc 3.3.1 and VC++ 7.1).[/color]
>>
>>
>> It does? Could you please post your version that compiles? Here is
>> my attempt:
>> ------------------------------------------------------------
>> template <typename T, typename V>
>> class Mask
>> {
>> public:
>> int i;
>> Mask(int i) {}
>> };
>>
>> enum DefaultValues
>> {
>> ZeroDefault,
>> NaNDefault,
>> WhateverDefault
>> };
>>
>> template<typename T, typename I, DefaultValues D>
>> struct DefaultElement
>> {
>> static const T value;
>> };
>>
>> template<typename T, typename V>
>> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>> {
>> static const Mask<T,V> value;
>> };
>>
>> int main()
>> {
>> DefaultElement<double, char> dedc; // **************
>> return dedc.value.i;
>> }
>> ------------------------------------------------------------
>> VC++ complains at the line marked with ***** saying "too few template
>> arguments". Have you actually attempted to instantiate DefaultElement?
>>[/color]
>
> --------------------------------------------------- This works with VC++
> Note that 'DefaultElement' is not specialised based on Mask<T,V> and T,
> but instead on T,V, and ZeroDefault.
> ------------------------------------------------------------------------
> template <typename T, typename V>
> class Mask
> {
> public:
> int i;
> Mask(int i) : i(i) {}
> };
>
> enum DefaultValues
> {
> ZeroDefault,
> NaNDefault,
> WhateverDefault
> };
>
> template<typename T, typename I, DefaultValues D>
> struct DefaultElement
> {
> static const T value;
> };
>
> template<typename T, typename V>
> struct DefaultElement<T,V,ZeroDefault>
> {
> static const Mask<T,V> value;
> };
>
> template<typename T, typename V>
> const Mask<T,V> DefaultElement<T,V,ZeroDefault>::value(42);
>
> int main()
> {
> DefaultElement<double,char,ZeroDefault> dedc;
> return dedc.value.i;
> }[/color]

Your solution here must be incorrect. It would match any instance with third
argument ZeroDefault, but it only should match if the first argument is
also Mask<T, V> and in no other case.

Alex

Victor Bazarov
Guest
 
Posts: n/a
#12: Jul 22 '05

re: template specialization


Alexander Stippler wrote:
[color=blue]
> Victor Bazarov wrote:
>
>[color=green]
>>Victor Bazarov wrote:
>>[color=darkred]
>>>John Harrison wrote:
>>>
>>>
>>>>On Mon, 19 Jul 2004 22:00:23 +0200, Alexander Stippler
>>>><stip@mathematik.uni-ulm.de> wrote:
>>>>
>>>>
>>>>>Victor Bazarov wrote:
>>>>>
>>>>>
>>>>>>Alexander Stippler wrote:
>>>>>
>>>>>
>>>>> ...
>>>>>
>>>>>
>>>>>>>Thus:
>>>>>>>
>>>>>>>template <typename T, typename V>
>>>>>>>const Mask<T, V>
>>>>>>>DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>>>>>>
>>>>>>>But what's wrong with it?
>>>>>>
>>>>>>
>>>>>>
>>>>>>Wrong? You're trying to _partially_ specialize a member without first
>>>>>>partially specializing the class itself.
>>>>>>
>>>>>>Victor
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>Yes, but how to do it:
>>>>>
>>>>>template <typename T, typename V>
>>>>>struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>>>>>{
>>>>> static const Mask<T, V> value;
>>>>>};
>>>>>
>>>>>This does not solve the problem. Inserting it into the code results in
>>>>>'template argument list must match the parameter list'.
>>>>>
>>>>>regards,
>>>>> Alex
>>>>>
>>>>
>>>>Then I think you have a broken compiler. That compiles on the two
>>>>compilers I tried it on (gcc 3.3.1 and VC++ 7.1).[/color][/color][/color]


I don't think John has verified it properly.

[color=blue][color=green][color=darkred]
>>>
>>>
>>>It does? Could you please post your version that compiles? Here is
>>>my attempt:
>>>------------------------------------------------------------
>>>template <typename T, typename V>
>>>class Mask
>>>{
>>>public:
>>> int i;
>>> Mask(int i) {}
>>>};
>>>
>>>enum DefaultValues
>>>{
>>> ZeroDefault,
>>> NaNDefault,
>>> WhateverDefault
>>>};
>>>
>>>template<typename T, typename I, DefaultValues D>
>>>struct DefaultElement
>>>{
>>> static const T value;
>>>};
>>>
>>>template<typename T, typename V>
>>>struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>>>{
>>> static const Mask<T,V> value;
>>>};
>>>
>>>int main()
>>>{
>>> DefaultElement<double, char> dedc; // **************
>>> return dedc.value.i;
>>>}
>>>------------------------------------------------------------
>>>VC++ complains at the line marked with ***** saying "too few template
>>>arguments". Have you actually attempted to instantiate DefaultElement?
>>>[/color]
>>
>>--------------------------------------------------- This works with VC++
>>Note that 'DefaultElement' is not specialised based on Mask<T,V> and T,
>>but instead on T,V, and ZeroDefault.
>>------------------------------------------------------------------------
>>template <typename T, typename V>
>>class Mask
>>{
>>public:
>> int i;
>> Mask(int i) : i(i) {}
>>};
>>
>>enum DefaultValues
>>{
>> ZeroDefault,
>> NaNDefault,
>> WhateverDefault
>>};
>>
>>template<typename T, typename I, DefaultValues D>
>>struct DefaultElement
>>{
>> static const T value;
>>};
>>
>>template<typename T, typename V>
>>struct DefaultElement<T,V,ZeroDefault>
>>{
>> static const Mask<T,V> value;
>>};
>>
>>template<typename T, typename V>
>>const Mask<T,V> DefaultElement<T,V,ZeroDefault>::value(42);
>>
>>int main()
>>{
>> DefaultElement<double,char,ZeroDefault> dedc;
>> return dedc.value.i;
>>}[/color]
>
>
> Your solution here must be incorrect. It would match any instance with third
> argument ZeroDefault, but it only should match if the first argument is
> also Mask<T, V> and in no other case.[/color]

Alex, I am not claiming it's "correct". I am simply demonstrating what
code I managed to get to compile on VC++ v7.1, contrary to what John
said in his last post (that it allegedly compiled with gcc and VC++).

Victor
Victor Bazarov
Guest
 
Posts: n/a
#13: Jul 22 '05

re: template specialization


Alexander Stippler wrote:[color=blue]
> [...]
>
> Are you sure? The general version has template parameter T and defines a
> constant of type T. The specialization uses Mask<T,V> as the former T and
> ZeroDefault as specialization of D. So if type Mask<T, V> replaced type T
> why isn't it
> DefaultElement<Mask<T,V>, T, ZeroDefault>
> ?[/color]

Alex, I am not trying to solve your problem here. If the first arg
of 'DefaultElement' needs to be Mask<T,V>, let it be. I am simply
showing that the form

template<class T, class V> class DE<Mask<T, V>, T, ZeroDefault>

cannot work. It attempts to specialise on a type that is an argument
of another template. You probably need to declare the first argument
of 'DE' as a _template_ for that.

Victor
Alexander Stippler
Guest
 
Posts: n/a
#14: Jul 22 '05

re: template specialization


Victor Bazarov wrote:
[color=blue]
> Alexander Stippler wrote:
>[color=green]
>> Victor Bazarov wrote:
>>
>>[color=darkred]
>>>Victor Bazarov wrote:
>>>
>>>>John Harrison wrote:
>>>>
>>>>
>>>>>On Mon, 19 Jul 2004 22:00:23 +0200, Alexander Stippler
>>>>><stip@mathematik.uni-ulm.de> wrote:
>>>>>
>>>>>
>>>>>>Victor Bazarov wrote:
>>>>>>
>>>>>>
>>>>>>>Alexander Stippler wrote:
>>>>>>
>>>>>>
>>>>>> ...
>>>>>>
>>>>>>
>>>>>>>>Thus:
>>>>>>>>
>>>>>>>>template <typename T, typename V>
>>>>>>>>const Mask<T, V>
>>>>>>>>DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>>>>>>>
>>>>>>>>But what's wrong with it?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>Wrong? You're trying to _partially_ specialize a member without
>>>>>>>first partially specializing the class itself.
>>>>>>>
>>>>>>>Victor
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>Yes, but how to do it:
>>>>>>
>>>>>>template <typename T, typename V>
>>>>>>struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>>>>>>{
>>>>>> static const Mask<T, V> value;
>>>>>>};
>>>>>>
>>>>>>This does not solve the problem. Inserting it into the code results in
>>>>>>'template argument list must match the parameter list'.
>>>>>>
>>>>>>regards,
>>>>>> Alex
>>>>>>
>>>>>
>>>>>Then I think you have a broken compiler. That compiles on the two
>>>>>compilers I tried it on (gcc 3.3.1 and VC++ 7.1).[/color][/color]
>
>
> I don't think John has verified it properly.
>
>[color=green][color=darkred]
>>>>
>>>>
>>>>It does? Could you please post your version that compiles? Here is
>>>>my attempt:
>>>>------------------------------------------------------------
>>>>template <typename T, typename V>
>>>>class Mask
>>>>{
>>>>public:
>>>> int i;
>>>> Mask(int i) {}
>>>>};
>>>>
>>>>enum DefaultValues
>>>>{
>>>> ZeroDefault,
>>>> NaNDefault,
>>>> WhateverDefault
>>>>};
>>>>
>>>>template<typename T, typename I, DefaultValues D>
>>>>struct DefaultElement
>>>>{
>>>> static const T value;
>>>>};
>>>>
>>>>template<typename T, typename V>
>>>>struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>>>>{
>>>> static const Mask<T,V> value;
>>>>};
>>>>
>>>>int main()
>>>>{
>>>> DefaultElement<double, char> dedc; // **************
>>>> return dedc.value.i;
>>>>}
>>>>------------------------------------------------------------
>>>>VC++ complains at the line marked with ***** saying "too few template
>>>>arguments". Have you actually attempted to instantiate DefaultElement?
>>>>
>>>
>>>--------------------------------------------------- This works with VC++
>>>Note that 'DefaultElement' is not specialised based on Mask<T,V> and T,
>>>but instead on T,V, and ZeroDefault.
>>>------------------------------------------------------------------------
>>>template <typename T, typename V>
>>>class Mask
>>>{
>>>public:
>>> int i;
>>> Mask(int i) : i(i) {}
>>>};
>>>
>>>enum DefaultValues
>>>{
>>> ZeroDefault,
>>> NaNDefault,
>>> WhateverDefault
>>>};
>>>
>>>template<typename T, typename I, DefaultValues D>
>>>struct DefaultElement
>>>{
>>> static const T value;
>>>};
>>>
>>>template<typename T, typename V>
>>>struct DefaultElement<T,V,ZeroDefault>
>>>{
>>> static const Mask<T,V> value;
>>>};
>>>
>>>template<typename T, typename V>
>>>const Mask<T,V> DefaultElement<T,V,ZeroDefault>::value(42);
>>>
>>>int main()
>>>{
>>> DefaultElement<double,char,ZeroDefault> dedc;
>>> return dedc.value.i;
>>>}[/color]
>>
>>
>> Your solution here must be incorrect. It would match any instance with
>> third argument ZeroDefault, but it only should match if the first
>> argument is also Mask<T, V> and in no other case.[/color]
>
> Alex, I am not claiming it's "correct". I am simply demonstrating what
> code I managed to get to compile on VC++ v7.1, contrary to what John
> said in his last post (that it allegedly compiled with gcc and VC++).
>
> Victor[/color]

Well, John's code compiled well with my gcc3.3.1. With a different choice of
template parameters as you have chosen, i.e.:

DefaultValue<Mask<double, long>, long, ZeroDefault>

Alex
Alexander Stippler
Guest
 
Posts: n/a
#15: Jul 22 '05

re: template specialization


Victor Bazarov wrote:
[color=blue]
> Alexander Stippler wrote:[color=green]
>> [...]
>>
>> Are you sure? The general version has template parameter T and defines a
>> constant of type T. The specialization uses Mask<T,V> as the former T and
>> ZeroDefault as specialization of D. So if type Mask<T, V> replaced type T
>> why isn't it
>> DefaultElement<Mask<T,V>, T, ZeroDefault>
>> ?[/color]
>
> Alex, I am not trying to solve your problem here. If the first arg
> of 'DefaultElement' needs to be Mask<T,V>, let it be. I am simply
> showing that the form
>
> template<class T, class V> class DE<Mask<T, V>, T, ZeroDefault>
>
> cannot work. It attempts to specialise on a type that is an argument
> of another template. You probably need to declare the first argument
> of 'DE' as a _template_ for that.
>
> Victor[/color]

It cannot work, but it does. Just tried it (finally in a 'real life
example'). Why is it not allowed?

Alex
Victor Bazarov
Guest
 
Posts: n/a
#16: Jul 22 '05

re: template specialization


Alexander Stippler wrote:[color=blue]
> Victor Bazarov wrote:
>
>[color=green]
>>Alexander Stippler wrote:
>>[color=darkred]
>>>[...]
>>>
>>>Are you sure? The general version has template parameter T and defines a
>>>constant of type T. The specialization uses Mask<T,V> as the former T and
>>>ZeroDefault as specialization of D. So if type Mask<T, V> replaced type T
>>>why isn't it
>>> DefaultElement<Mask<T,V>, T, ZeroDefault>
>>>?[/color]
>>
>>Alex, I am not trying to solve your problem here. If the first arg
>>of 'DefaultElement' needs to be Mask<T,V>, let it be. I am simply
>>showing that the form
>>
>> template<class T, class V> class DE<Mask<T, V>, T, ZeroDefault>
>>
>>cannot work. It attempts to specialise on a type that is an argument
>>of another template. You probably need to declare the first argument
>>of 'DE' as a _template_ for that.
>>
>>Victor[/color]
>
>
> It cannot work, but it does. Just tried it (finally in a 'real life
> example'). Why is it not allowed?[/color]

I don't know why all compilers I tried on can't accept them. What exactly
have you done to make it work and on what compiler? Can you post the same
short code like I did?

V
John Harrison
Guest
 
Posts: n/a
#17: Jul 22 '05

re: template specialization


On Mon, 19 Jul 2004 20:17:34 GMT, Victor Bazarov <v.Abazarov@comAcast.net>
wrote:
[color=blue]
> John Harrison wrote:[color=green]
>> On Mon, 19 Jul 2004 22:00:23 +0200, Alexander Stippler
>> <stip@mathematik.uni-ulm.de> wrote:
>>[color=darkred]
>>> Victor Bazarov wrote:
>>>
>>>> Alexander Stippler wrote:
>>>
>>> ...
>>>
>>>>> Thus:
>>>>>
>>>>> template <typename T, typename V>
>>>>> const Mask<T, V>
>>>>> DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);
>>>>>
>>>>> But what's wrong with it?
>>>>
>>>>
>>>> Wrong? You're trying to _partially_ specialize a member without first
>>>> partially specializing the class itself.
>>>>
>>>> Victor
>>>
>>>
>>>
>>> Yes, but how to do it:
>>>
>>> template <typename T, typename V>
>>> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
>>> {
>>> static const Mask<T, V> value;
>>> };
>>>
>>> This does not solve the problem. Inserting it into the code results in
>>> 'template argument list must match the parameter list'.
>>>
>>> regards,
>>> Alex
>>>[/color]
>> Then I think you have a broken compiler. That compiles on the two
>> compilers I tried it on (gcc 3.3.1 and VC++ 7.1).[/color]
>
> It does? Could you please post your version that compiles? Here is
> my attempt:
> ------------------------------------------------------------
> template <typename T, typename V>
> class Mask
> {
> public:
> int i;
> Mask(int i) {}
> };
>
> enum DefaultValues
> {
> ZeroDefault,
> NaNDefault,
> WhateverDefault
> };
>
> template<typename T, typename I, DefaultValues D>
> struct DefaultElement
> {
> static const T value;
> };
>
> template<typename T, typename V>
> struct DefaultElement<Mask<T, V>, T, ZeroDefault>
> {
> static const Mask<T,V> value;
> };
>
> int main()
> {
> DefaultElement<double, char> dedc; // **************
> return dedc.value.i;
> }
> ------------------------------------------------------------
> VC++ complains at the line marked with ***** saying "too few template
> arguments". Have you actually attempted to instantiate DefaultElement?
>
> V[/color]

Here

#include <iostream>
using namespace std;

template <typename T, typename V>
class Mask
{
public:
Mask(int i) {}
};

enum DefaultValues
{
ZeroDefault,
NaNDefault,
WhateverDefault
};

template <typename T, typename I, DefaultValues D>
struct DefaultElement
{
static const T value;
};

template <typename T, typename I, DefaultValues D>
const T
DefaultElement<T, I, D>::value = T();

template <typename T, typename V>
struct DefaultElement<Mask<T, V>, T, ZeroDefault>
{
static const Mask<T, V> value;
static const int tester = 1;
};

template <typename T, typename V>
const Mask<T, V>
DefaultElement<Mask<T, V>, T, ZeroDefault>::value = Mask<T, V>(1);

int main()
{
DefaultElement<Mask<int,int>, int, ZeroDefault> x;
std::cout << x.tester << '\n'
return 0;
}

tester has been added to the specialisation to prove that it has been
instantiated. Am I missing the point?

john
Victor Bazarov
Guest
 
Posts: n/a
#18: Jul 22 '05

re: template specialization


John Harrison wrote:[color=blue]
> [...]
> tester has been added to the specialisation to prove that it has been
> instantiated. Am I missing the point?[/color]

No, I was. Sorry to have wasted bandwidth.

I think I was trying to solve a wrong problem. This is what I tried:

template<class T, class U, int i> struct A { enum { original }; };
template<class T, class U> struct B {};
template<class T, class U> struct A<B<T,U>,T,0> { enum { spec }; };

int main() {
return A<B<int,char>,int>::spec;
// ^^^^^^^^^^^^^^^ only 2 arguments
}

it doesn't compile. Why? Because partial specialisations are not
found during lookup. You cannot specify only two arguments. There
needs to be three:

template<class T, class U, int i> struct A { enum { original }; };
template<class T, class U> struct B {};
template<class T, class U> struct A<B<T,U>,T,0> { enum { spec }; };

int main() {
return A<B<int,char>,int,0>::spec;
}

Now it compiles fine.

Victor
Closed Thread