By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,423 Members | 1,327 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,423 IT Pros & Developers. It's quick & easy.

Partial specialisation

P: n/a
Hi,

The following code is legal, and works as expected:

#include <iostream>

template <typename T>
class Bar {
};

template <typename T, typename P>
class Foo {
public:
void doStuff();
};
template <typename T, typename P>
void Foo<T, P>::doStuff() {
std::cout << "General" << std::endl;
}

int main() {
Foo<float, Bar<float a;
a.doStuff();

Foo<float, floatb;
b.doStuff();

return 0;
}
But none of these specialise the method doStuff():

// Not valid:
template <typename T>
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;
}

// Not valid:
template <typename T, typename P=Bar<T
void Foo<T, P>::doStuff() {
std::cout << "Specific" << std::endl;
}

// Not valid:
template <typename T, Bar<T
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;
}

Is there a valid way to achieve this without using a non member template
function and calling that from within the generic doStuff()?

Thanks,
Alan
May 17 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Alan Woodland wrote:
The following code is legal, and works as expected:

#include <iostream>

template <typename T>
class Bar {
};

template <typename T, typename P>
class Foo {
public:
void doStuff();
};
template <typename T, typename P>
void Foo<T, P>::doStuff() {
std::cout << "General" << std::endl;
}

int main() {
Foo<float, Bar<float a;
a.doStuff();

Foo<float, floatb;
b.doStuff();

return 0;
}
But none of these specialise the method doStuff():

// Not valid:
template <typename T>
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;
}

// Not valid:
template <typename T, typename P=Bar<T
void Foo<T, P>::doStuff() {
std::cout << "Specific" << std::endl;
}

// Not valid:
template <typename T, Bar<T
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;
}

Is there a valid way to achieve this without using a non member
template function and calling that from within the generic doStuff()?
No. What you're attempting to do here is to create an _implicit_
partial specialisation of a class template through defining a single
member of it (and without defining the actual partial specialisation
of the class template). That's impossible. You need to define the
entire class template (by repeating most of it) and then define the
member that is different from the unspecialised template.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 17 '07 #2

P: n/a
On May 17, 9:10 am, Alan Woodland <a...@aber.ac.ukwrote:
Hi,

The following code is legal, and works as expected:

#include <iostream>

template <typename T>
class Bar {

};

template <typename T, typename P>
class Foo {
public:
void doStuff();

};

template <typename T, typename P>
void Foo<T, P>::doStuff() {
std::cout << "General" << std::endl;

}

int main() {
Foo<float, Bar<float a;
a.doStuff();

Foo<float, floatb;
b.doStuff();

return 0;

}

But none of these specialise the method doStuff():

// Not valid:
template <typename T>
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;

}

// Not valid:
template <typename T, typename P=Bar<T
void Foo<T, P>::doStuff() {
std::cout << "Specific" << std::endl;

}

// Not valid:
template <typename T, Bar<T
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;

}

Is there a valid way to achieve this without using a non member template
function and calling that from within the generic doStuff()?

Thanks,
Alan
You can not specialize the method but you can specialize the class.
Try this.

template <typename T>
class Foo<T,Bar<T {
public:
void doStuff();
};

template <typename T>
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;

}

May 17 '07 #3

P: n/a
siddhu wrote:
On May 17, 9:10 am, Alan Woodland <a...@aber.ac.ukwrote:
>Hi,

The following code is legal, and works as expected:

#include <iostream>

template <typename T>
class Bar {

};

template <typename T, typename P>
class Foo {
public:
void doStuff();

};

template <typename T, typename P>
void Foo<T, P>::doStuff() {
std::cout << "General" << std::endl;

}

int main() {
Foo<float, Bar<float a;
a.doStuff();

Foo<float, floatb;
b.doStuff();

return 0;

}

But none of these specialise the method doStuff():

// Not valid:
template <typename T>
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;

}

// Not valid:
template <typename T, typename P=Bar<T
void Foo<T, P>::doStuff() {
std::cout << "Specific" << std::endl;

}

// Not valid:
template <typename T, Bar<T
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;

}

Is there a valid way to achieve this without using a non member
template function and calling that from within the generic doStuff()?

Thanks,
Alan

You can not specialize the method but you can specialize the class.
Try this.

template <typename T>
class Foo<T,Bar<T {
public:
void doStuff();
};

template <typename T>
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;

}
This is usually a problem if the need is to [partially] specialise
a single member function out of dozens. Having to specialise the
entire class template means you need to repeat all but one functions
and give them /exactly same/ implementation as the non-specialised
template.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 17 '07 #4

P: n/a
Victor Bazarov wrote:
siddhu wrote:
>On May 17, 9:10 am, Alan Woodland <a...@aber.ac.ukwrote:
[snip]
>>Is there a valid way to achieve this without using a non member
template function and calling that from within the generic doStuff()?

Thanks,
Alan
You can not specialize the method but you can specialize the class.
Try this.

template <typename T>
class Foo<T,Bar<T {
public:
void doStuff();
};

template <typename T>
void Foo<T, Bar<T::doStuff() {
std::cout << "Specific" << std::endl;

}

This is usually a problem if the need is to [partially] specialise
a single member function out of dozens. Having to specialise the
entire class template means you need to repeat all but one functions
and give them /exactly same/ implementation as the non-specialised
template.
For reference the solution I went with in the end was:

#include <iostream>

template <typename T>
class Bar {
};

template <typename T, typename P>
class DoStuffImpl {
public:
static void apply() {
std::cout << "General" << std::endl;
}
};

template <typename T>
class DoStuffImpl<T, Bar<T {
public:
static void apply() {
std::cout << "Specific" << std::endl;
}
};

template <typename T, typename P>
class Foo {
public:
void doStuff();
};
template <typename T, typename P>
void Foo<T, P>::doStuff() {
DoStuffImpl<T, P>::apply();
}

int main() {
Foo<float, Bar<float a;
a.doStuff();

Foo<float, floatb;
b.doStuff();

return 0;
}

Which does what I wanted (i.e. not having to repeat all the other
members) via an additional level of indirection (that probably can be
optimised by a decent compiler anyway)

Thanks,
Alan
May 18 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.