partial template specialization | | |
I'm confused as to the syntax for partial template specialization.
Below is a very small example. Can someone tell me what I should do to
make this compile properly on an ISO-compliant compiler?
template <typename T1, typename T2>
class A
{
public:
T1 t1;
T2 t2;
};
template <typename T1, typename T2>
class B
{
public:
void insert(A<T1, T2f);
};
template <typename T1>
void B<T1, int>::insert(A<T1, intf)
{
f.t1 = 0;
f.t2 = 0;
}
template <typename T1, typename T2>
void B<T1, T2>::insert(A<T1, T2f)
{
f.t1 = 0;
f.t2 = 0;
}
int main()
{
A<int, inta1;
A<float, floata2;
B<int, intb1;
B<float, floatb2;
b1.insert(a1);
b2.insert(a2);
return 0;
} | | | | re: partial template specialization cpunerd@gmail.com wrote: Quote:
I'm confused as to the syntax for partial template specialization.
Below is a very small example. Can someone tell me what I should do to
make this compile properly on an ISO-compliant compiler?
>
template <typename T1, typename T2>
class A
{
public:
T1 t1;
T2 t2;
};
>
template <typename T1, typename T2>
class B
{
public:
void insert(A<T1, T2f);
};
>
template <typename T1>
void B<T1, int>::insert(A<T1, intf)
{
f.t1 = 0;
f.t2 = 0;
}
You've attempted to partially specialise a member function. That's not
allowed. You may partially specialise the whole class only.
Besides, I can't see why you'd want to do that. Both functions
are exactly the same. Quote:
template <typename T1, typename T2>
void B<T1, T2>::insert(A<T1, T2f)
{
f.t1 = 0;
f.t2 = 0;
}
>
int main()
{
A<int, inta1;
A<float, floata2;
B<int, intb1;
B<float, floatb2;
>
b1.insert(a1);
b2.insert(a2);
>
return 0;
}
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask | | | | re: partial template specialization
On Apr 30, 8:21 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote: Quote:
cpun...@gmail.com wrote: Quote:
I'm confused as to the syntax for partial template specialization.
Below is a very small example. Can someone tell me what I should do to
make this compile properly on an ISO-compliant compiler?
> Quote:
template <typename T1, typename T2>
class A
{
public:
T1 t1;
T2 t2;
};
> Quote:
template <typename T1, typename T2>
class B
{
public:
void insert(A<T1, T2f);
};
> Quote:
template <typename T1>
void B<T1, int>::insert(A<T1, intf)
{
f.t1 = 0;
f.t2 = 0;
}
>
You've attempted to partially specialise a member function. That's not
allowed. You may partially specialise the whole class only.
>
Besides, I can't see why you'd want to do that. Both functions
are exactly the same.
>
>
> Quote:
template <typename T1, typename T2>
void B<T1, T2>::insert(A<T1, T2f)
{
f.t1 = 0;
f.t2 = 0;
}
> Quote:
int main()
{
A<int, inta1;
A<float, floata2;
B<int, intb1;
B<float, floatb2;
> Quote:
b1.insert(a1);
b2.insert(a2);
> >
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
in this case both functions are exactly the same. it is simply a
trivial example to show the problem, which is as you said, you cant
partially specialize a member function. the instance in where i am
trying to do something like this is indeed useful, pity... thanks for
the help though. is there a better idea that you can think of than
making a friend function and specializing the friend function? | | | | re: partial template specialization cpunerd@gmail.com wrote: Quote:
On Apr 30, 8:21 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote: Quote:
>cpun...@gmail.com wrote: Quote:
>>I'm confused as to the syntax for partial template specialization.
>>Below is a very small example. Can someone tell me what I should do
>>to make this compile properly on an ISO-compliant compiler?
>> Quote:
>>template <typename T1, typename T2>
>>class A
>>{
>> public:
>> T1 t1;
>> T2 t2;
>>};
>> Quote:
>>template <typename T1, typename T2>
>>class B
>>{
>> public:
>> void insert(A<T1, T2f);
>>};
>> Quote:
>>template <typename T1>
>>void B<T1, int>::insert(A<T1, intf)
>>{
>> f.t1 = 0;
>> f.t2 = 0;
>>}
>>
>You've attempted to partially specialise a member function. That's
>not allowed. You may partially specialise the whole class only.
>>
>Besides, I can't see why you'd want to do that. Both functions
>are exactly the same.
>>
>>
>> Quote:
>>template <typename T1, typename T2>
>>void B<T1, T2>::insert(A<T1, T2f)
>>{
>> f.t1 = 0;
>> f.t2 = 0;
>>}
>> Quote:
>>int main()
>>{
>> A<int, inta1;
>> A<float, floata2;
>> B<int, intb1;
>> B<float, floatb2;
>> Quote:
>> b1.insert(a1);
>> b2.insert(a2);
>> >>
>V
>--
>Please remove capital 'A's when replying by e-mail
>I do not respond to top-posted replies, please don't ask
>
in this case both functions are exactly the same. it is simply a
trivial example to show the problem, which is as you said, you cant
partially specialize a member function. the instance in where i am
trying to do something like this is indeed useful, pity... thanks for
the help though. is there a better idea that you can think of than
making a friend function and specializing the friend function?
One approach:
--------------------------
template<class T, class Ustruct A
{
};
template<class Ustruct NotInt { enum { yes = 1 }; };
template<struct NotInt<int{ enum { yes = 0 }; };
template<class T, class Ustruct B
{
void foo_generic(A<T,U>& a)
{
cout << "Generic\n";
}
void foo_int(A<T,U>& a)
{
cout << "Specialised\n";
}
void foo(A<T,U>& a)
{
if (NotInt<U>::yes)
foo_generic(a);
else
foo_int(a);
}
};
--------------------------
Another approach:
--------------------------
template<class T, class Ustruct A
{
};
template<class Ustruct NotInt { static const size_t s = 1; };
template<struct NotInt<int{ static const size_t s = 0; };
template<class T, class Ustruct B
{
template<size_t S>
void foo_helper(A<T,U>& a, int (*)[S] = 0) // OK for non-int 'U'
{
cout << "Generic\n";
}
template<size_t S>
void foo_helper(A<T,U>& a, int (*)[1-S] = 0) // OK only for int 'U'
{
cout << "Specialised\n";
}
void foo(A<T,U>& a)
{
foo_helper<NotInt<U>::s>(a);
}
};
--------------------------
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask | | | | re: partial template specialization
Victor Bazarov wrote: Quote:
--------------------------
>
Another approach:
--------------------------
template<class T, class Ustruct B
{
template<size_t S>
void foo_helper(A<T,U>& a, int (*)[S] = 0) // OK for non-int 'U'
>
template<size_t S>
void foo_helper(A<T,U>& a, int (*)[1-S] = 0) // OK only for int 'U'
Can you explain what are these things? I have not seen them so far.
Under "these things" I meant:
int (*)[S]=0
and
int (*)[1-S]=0 | | | | re: partial template specialization
anon wrote: Quote:
Victor Bazarov wrote: Quote:
>--------------------------
>>
>Another approach:
>--------------------------
>template<class T, class Ustruct B
>{
> template<size_t S>
> void foo_helper(A<T,U>& a, int (*)[S] = 0) // OK for non-int 'U'
>>
> template<size_t S>
> void foo_helper(A<T,U>& a, int (*)[1-S] = 0) // OK only for int
>'U'
>
>
Can you explain what are these things? I have not seen them so far.
Under "these things" I meant:
int (*)[S]=0
and
int (*)[1-S]=0
It's a pointer to an array of size 'S' and of size '1-S', respectively.
Since I'm not using that pointer for anything, the name of the array is
omitted (it would follow the asterisk), and since I didn't want to put
the value at the place where 'foo_helper' is called, I gave the argument
the default value 0 (null pointer) -- that's the "=0". Alternatively,
I could have written
foo_helper(A<T,U>& a, int (*dummy)[S]) ...
and then call it
foo_helper(a, 0);
(same for the 1-S version of the 'helper').
The technique is called SFINAE. Check it out, it's very convenient.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,419 network members.
|