Connecting Tech Pros Worldwide Forums | Help | Site Map

partial template specialization

cpunerd@gmail.com
Guest
 
Posts: n/a
#1: May 1 '07
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;
}


Victor Bazarov
Guest
 
Posts: n/a
#2: May 1 '07

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


cpunerd@gmail.com
Guest
 
Posts: n/a
#3: May 1 '07

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);
>
Quote:
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
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?

Victor Bazarov
Guest
 
Posts: n/a
#4: May 1 '07

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);
>>
Quote:
>> 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
>
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


anon
Guest
 
Posts: n/a
#5: May 1 '07

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
Victor Bazarov
Guest
 
Posts: n/a
#6: May 1 '07

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


Closed Thread