From: fondwey on

Hi all,

does anyone have an idea how to specialice a function template when the
type does not occur in the parameter list ?

Example:


template <class T> class TheClass
{
private:

std::string a_;
std::string b_;


public:

void dosomething()
{
foo<T>( a_, b_ );
}


};


template<class T> void foo( std::string& a, const std::string& b )
{
// default do nothing
}


template<std::string> void foo( std::string& a, const std::string& b )
{
// do what has to be done for strings
}


Now when i use this code:

TheClass<std::string> theclass;


theclass.dosomething(); // calls default foo not specialized foo


Does anyone know what i am doing wrong ?

Thanks in advance,

Joe


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Victor Bazarov on
fondwey(a)yahoo.com wrote:
> does anyone have an idea how to specialice a function template when the
> type does not occur in the parameter list ?
>
> Example:
>
>
> template <class T> class TheClass
> {
> private:
>
> std::string a_;
> std::string b_;
>
>
> public:
>
> void dosomething()
> {
> foo<T>( a_, b_ );
> }
>
>
> };
>
>
> template<class T> void foo( std::string& a, const std::string& b )
> {
> // default do nothing
> }
>
>
> template<std::string> void foo( std::string& a, const std::string& b )

You mean:

template<> void foo<std::string>( ...

don't you?

> {
> // do what has to be done for strings
> }
>
>
> Now when i use this code:
>
> TheClass<std::string> theclass;
>
>
> theclass.dosomething(); // calls default foo not specialized foo
>
>
> Does anyone know what i am doing wrong ?

You're using wrong syntax to define a specialisation. Doesn't your
compiler tell you that?

--------------- This code
#include <string>

template<class T> class TheClass
{
std::string a_;
std::string b_;
public:
void dosomething()
{
foo<T>( a_, b_ );
}
};

#include <iostream>

template<class T> void foo( std::string& a, const std::string& b )
{
// default do nothing
std::cout << "default\n";
}

template<> void foo<std::string>( std::string& a, const std::string& b )
{
// do what has to be done for strings
std::cout << "special\n";
}

int main()
{
TheClass<int> tci;
TheClass<std::string> tcs;
tci.dosomething();
tcs.dosomething();
}
--------------- outputs
default
special
------------------------
Apparently, as you intend it to. I didn't test it on all available to me
compilers, but if it doesn't work for you, move the 'foo' definitions
before the 'TheClass' template definition.

V

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Thomas Tutone on
fondwey(a)yahoo.com wrote:

> does anyone have an idea how to specialice a function template when the
> type does not occur in the parameter list ?
>
> Example:
>
> template <class T> class TheClass
> {
> private:
> std::string a_;
> std::string b_;
> public:
> void dosomething()
> {
> foo<T>( a_, b_ );
> }
> };
>
> template<class T> void foo( std::string& a, const std::string& b )
> {
> // default do nothing
> }
>
> template<std::string> void foo( std::string& a, const std::string& b )
> {
> // do what has to be done for strings
> }
>
> Now when i use this code:
>
> TheClass<std::string> theclass;
>
> theclass.dosomething(); // calls default foo not specialized foo
>
> Does anyone know what i am doing wrong ?

You're using the wrong syntax to declare and define the the std::string
specialization of foo(). Try this:

#include <string>
#include <iostream>
#include <ostream>

template<class T>
void foo(std::string& a,
const std::string& b)
{ std::cout << "Default foo()"; }

template<>
void foo<std::string>(std::string& a,
const std::string& b )
{ std::cout << "foo<std::string>()"; }

template <class T> class TheClass {
std::string a_, b_;
public:
void dosomething()
{ foo<T>( a_, b_ ); }
};

int main()
{
TheClass<std::string> theclass;
theclass.dosomething();
}

Best regards,

Tom


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ale? Pergl on
> Hi all,
>
> does anyone have an idea how to specialice a function template when
> the type does not occur in the parameter list ?
>
> Example:
>
> template <class T> class TheClass
> {
> private:
> std::string a_;
> std::string b_;
> public:
>
> void dosomething()
> {
> foo<T>( a_, b_ );
> }
> };
>
> template<class T> void foo( std::string& a, const std::string& b )
> {
> // default do nothing
> }
> template<std::string> void foo( std::string& a, const std::string& b )
> {
> // do what has to be done for strings
> }
> Now when i use this code:
>
> TheClass<std::string> theclass;
>
> theclass.dosomething(); // calls default foo not specialized foo
>
> Does anyone know what i am doing wrong ?
>
> Thanks in advance,
>
> Joe

You thought you wrote a function template specialization but actually you
wrote another function template whose template argument is a non-type parameter
std::string. The code is legal but means something else than you intended.
The correct syntax for template specialization is this:

template<> void foo<std::string>( std::string& a, const std::string& b ) {}

Regards,
A.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Eugene Alterman on
"Victor Bazarov" <v.Abazarov(a)comAcast.net> wrote in message
news:Xf4Ef.535$a97.432(a)newsread1.mlpsca01.us.to.verio.net...
> fondwey(a)yahoo.com wrote:

[snip]

>> template<class T> void foo( std::string& a, const std::string& b )
>> {
>> // default do nothing
>> }
>>
>>
>> template<std::string> void foo( std::string& a, const std::string& b )
>
> You mean:
>
> template<> void foo<std::string>( ...
>
> don't you?
>
>> {
>> // do what has to be done for strings
>> }
>>
>>
>> Now when i use this code:
>>
>> TheClass<std::string> theclass;
>>
>>
>> theclass.dosomething(); // calls default foo not specialized foo
>>
>>
>> Does anyone know what i am doing wrong ?
>
> You're using wrong syntax to define a specialisation. Doesn't your
> compiler tell you that?

The "specialization" actually declares an unrelated template with a non-type
parameter of std::string type.
Since non-type template parameters of class type are not allowed this
template declaration is ill-formed.

Microsoft VC7.1 compiles it without any diagnostics, but gives a correct
error message if a parameter name is provided:
template<std::string str> void foo( std::string& a, const std::string& b).

It is obviously a compiler bug.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]