Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Specializing Member Function Template of Class Template?

Reply
Thread Tools

Specializing Member Function Template of Class Template?

 
 
Simon G Best
Guest
Posts: n/a
 
      12-29-2006
Hello!

I'm trying to specialize a member function template of a class template,
like this:-

template<typename T> class thingy {
public:
template<typename U> T f (const U &) const;
};

// The general case:-
template<typename T> template<typename U> T thingy<T>::f
(const U &x) const {
return T(x);
}

// The special case:-
template<typename T> template<> T thingy<T>::f<T>
(const T &x) const {
return x;
}

But it's not working I've tried a few variations (such as throwing
in a 'template' to disambiguate), but my compilers (G++ 4.1.2 and G++
3.3.6) just don't seem to like it. With the above C++, I'm getting the
following out of G++ 4.1.2:-

templates.cpp:13: error: invalid explicit specialization before ‘>’ token
templates.cpp:13: error: enclosing class templates are not explicitly
specialized
templates.cpp:14: error: template-id ‘f<T>’ for ‘T thingy<T>::f(const
T&) const’ does not match any template declaration
templates.cpp:14: error: invalid function declaration



What am I doing wrong?

Simon

--
What happens if I mention Leader Kibo in my .signature?
 
Reply With Quote
 
 
 
 
kwikius
Guest
Posts: n/a
 
      12-29-2006

Simon G Best wrote:


> What am I doing wrong?


Beacause the *parent* class is a template this is not allowed IIRC,
because someone could specialise the parent class which could cause
ambiguities. That is the rationale or something like it.

If you have boost you can try the enable_if technique --->

(Actually you could easily make your own versions of enable_if and
is_same if you dont have boost , but do put attribution to the
designers of course):

#include <boost/utility/enable_if.hpp>
//http://www.boost.org/libs/utility/enable_if.html
#include <boost/type_traits/is_same.hpp>
//http://www.boost.org/doc/html/boost_typetraits.html
#include <iostream>

Not sure if it works on older gcc though. Tested on VC7.1 and gcc4.1.

//--------------------------

template<typename T> class thingy {
public:

/*template <typename U>
T f( U const & x) const;*/

template<typename U>
typename boost::enable_if<
boost::is_same<T,U>,
T
>::type

f (const U &) const;

template<typename U>
typename boost::disable_if<
boost::is_same<T,U>,
T
>::type

f (const U &) const;
};


// The general case:-
template<typename T>
template<typename U>
typename boost::disable_if<
boost::is_same<T,U>,
T
>::type

thingy<T>::f (const U &x) const {

std::cout << "general case\n";
return T(x);
}
// special case
template<typename T>
template<typename U>
typename boost::enable_if<
boost::is_same<T,U>,
T
>::type

thingy<T>::f
(const U &x) const {
std::cout << "special case\n";
return x;
}


int main()
{
thingy <int> n;
n.f(1);
n.f(2.0);
}

regards
Andy Little

 
Reply With Quote
 
 
 
 
Simon G Best
Guest
Posts: n/a
 
      12-29-2006
kwikius wrote:
>
> Beacause the *parent* class is a template this is not allowed IIRC,
> because someone could specialise the parent class which could cause
> ambiguities. That is the rationale or something like it.
>
> If you have boost you can try the enable_if technique --->

[...]

Thanks, but I don't think changing the class template itself is
justified, as my intended specialization isn't part of the interface,
but only for dealing with implementation details.

What I could do, though, is something like the following:-

[Start C++ here.]
#include <iostream>

template<typename T> class thingy {
public:
template<typename U> T f (const U &) const;
};

namespace {

/* Here's how I can get the kind of specialization I'm after.
*/

// The general case:-
template<typename T, typename U> class thingy_f_implementation {
public:
static T f (const U &x) {
::std::clog << "General." << ::std::endl;
return T(x);
}
};

// The special case:-
template<typename T> class thingy_f_implementation<T, T> {
public:
static T f (const T &x) {
::std::clog << "Special." << ::std::endl;
return x;
}
};
}

template<typename T> template<typename U> T thingy<T>::f
(const U &x) const {
return thingy_f_implementation<T, U>::f(x);
}

/* And just to prove it works:-
*/

int main () {
thingy<int> x;
x.f(float(2.3));
x.f(int(42));
return 0;
}
[End C++ here.]

But I'd rather do it more directly, as indicated in my original post. I
hoped it was just that I'd messed up the syntax, or something. But if,
as you say, it just can't be done that way, then I suppose taking the
scenic route (as above) would have to be it.

But thanks for your suggestion anyway

Simon

--
What happens if I mention Leader Kibo in my .signature?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
specializing a template function in a class John C++ 3 08-17-2010 09:00 AM
Specializing template member function Igor R. C++ 4 11-11-2009 11:02 AM
partially specializing member functions of a template class Rahul C++ 8 07-16-2007 02:22 PM
parse error in gcc but success in vc.net, call a non_template class's template member function from a template class's member function! ken C++ 2 06-28-2005 06:57 AM
Trouble specializing a member function in a template class Jeff C++ 2 11-20-2003 04:39 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57