-2

Following Template class type-specific functions, how can I customize my template code to not compile for certain types? If the question is not clear, take a look at this example.

///** template class ***/ template<typename T> class testClass{ testClass(); T parameter; } template<typename T> void testClass<T>::print(){cout<<parameter.value<<endl;} 

The above class is supposed to work for the following types:

 //** types file **/ class paramtype1{ int value; } class paramtype2{ int value; } class paramtype3{ } 

As you see, paramtype3 doesn't have value, so I get a compile error saying that value is not defined. I know that if I want to specialize a template class function for a certain type (s), I need to do:

template<> void testClass<paramtype1>::print(){cout<<parameter.value<<endl;} 

But, is there any way to do the other way around, only excluding some certain types?

2
  • You should edit your question to include what types specifically you want to include/exclude, and why. If you want to enable a specialization only if a type has a particular member, you'd use different techniques. Commented Jul 25, 2019 at 12:11
  • Also, you got a compiler error when you tried to use the template with paramtype3... doesn't that mean it already didn't compile for that type? Commented Jul 25, 2019 at 12:13

2 Answers 2

3

If you want enable/disable the full class/struct, you can use SFINAE and partial specialization.

The following is a C++17 example

template <typename T, typename = void> struct testClass; template <typename T> struct testClass<T, std::void_t<decltype(T::value)>> { testClass() { }; T parameter; void print() { std::cout << parameter.value << std::endl; } }; 

If you only want enable/disable the print() function, you have to templatize it; by example

template <typename U = T> std::void_t<decltype(U::value)> print() { std::cout << parameter.value << std::endl; } 

or also

template <typename U = T> std::void_t<decltype(U::value), std::enable_if_t<std::is_same_v<U, T>>> print() { std::cout << parameter.value << std::endl; } 

if you want to be sure that nobody can "hijack" the method explicating the template type calling

testClass<paramtype3>{}.print<paramtype1>(): 
Sign up to request clarification or add additional context in comments.

Comments

2

What I would personally do to exclude permissions to use certain types is:

template <class T, class... Ts> struct is_any : std::disjunction<std::is_same<T, Ts>...> {}; // https://stackoverflow.com/questions/17032310/how-to-make-a-variadic-is-same template <typename T> void do_something() { static_assert(!is_any<T, int, bool>::value, "do_something<T> cannot be used with T as int or bool"); // code here } 

Allows you to add a custom assertion message aswel, making it easy to realise what's wrong.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.