C ++ method extension

Can you specialize a template method in a template class without specializing in a template template parameter?

Please note that specialization depends on the value of the template parameter, and not on its type.

This is similar to compiling in Visual Studio 2008 SP1, but not GCC 4.2.4.

#include <iostream> using namespace std; template <typename T> class A { private: template <bool b> void testme(); template <> void testme<true>() { cout << "true" << endl; }; template <> void testme<false>() { cout << "false" << endl; }; public: void test(); }; template<typename T> struct select {}; template<> struct select<int> { static const bool value = true; }; template<> struct select<double> { static const bool value = false; }; template <class T> void A<T>::test() { testme<select<T>::value>(); } int main(int argc, const char* argv[]) { A<int> aInt; A<double> aDouble; aInt.test(); aDouble.test(); return 0; } 

GCC tells me: β€œerror: explicit specialization in namespace without class A class”

If it is not supported by the standard, can someone tell me why?

+4
source share
4 answers

Here is another workaround, also useful when you need to partially specialize a function (which is unacceptable). Create a template functor class (i.e. a Class whose sole purpose is to execute a single member function, usually called operator ()), specialization, and then call from your template function.

I think I learned this trick from Herb Sutter, but I don’t remember which book (or article) was like that. For your needs this is probably too much, but nonetheless ...

 template <typename T> struct select; template <bool B> struct testme_helper { void operator()(); }; template <typename T> class A { private: template <bool B> void testme() { testme_helper<B>()(); } public: void test() { testme<select<T>::value>(); } }; template<> void testme_helper<true>::operator()() { std::cout << "true" << std::endl; } template<> void testme_helper<false>::operator()() { std::cout << "false" << std::endl; } 
+1
source

It is not supported by the standard (and, apparently, this is a known bug with Visual Studio that you can make).

The standard does not allow you to specialize an internal template (member function or class) without a specialized external template. One reason for this is that you can usually simply overload a function:

 template<typename ty> class A { public: void foo(bool b); void foo(int i); }; 

It is equivalent to:

 template<typename ty> class A { public: template<typename ty2> void foo(ty2); template<> void foo(bool b); template<> void foo(int i); }; 
+4
source

this is how you do it:

 template<typename A> struct SomeTempl { template<bool C> typename enable_if<C>::type SomeOtherTempl() { std::cout << "true!"; } template<bool C> typename enable_if<!C>::type SomeOtherTempl() { std::cout << "false!"; } }; 

You can get enable_if from my other answer, where I told them how to check for the existence of a member function in a class using templates. or you can use boost, but remember to change enable_if to enable_if_c .

+2
source

I have never heard that this is possible; this would make sense to me if it were not supported by all compilers. So here is the idea of ​​a workaround:

Implement a template function outside of your class that performs the same actions as the method. Then you can specialize this function, and it calls it from a method. Of course, you will also have to pass in any member variables that it needs (and pointers to them if you want to change their values).

You can also create another class of templates as a subclass and specialize in this, although I have never done it myself and am not 100% sure that it will work. (Comment to enlarge this answer if you know if this second approach will work!)

0
source

Source: https://habr.com/ru/post/1276696/


All Articles