Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add member function of template class only on specific types using type_traits | C++

Tags:

c++

c++17

sfinae

template <typename T>
class A
{
        template <std::enable_if_t<std::is_signed_v<T>, bool> = true>
        constexpr value_type determinant()
        {
            
        }
}

I wanna determinant function is instantiated only when type T is signed type so I try this codes, but when type T is unsigned compiler still try instantiate determinant function.

I don't wanna specialize template function about each signed type T.
I want to use std::is_signed_v type traits to simplify codes

like image 853
SungJinKang Avatar asked Nov 02 '25 06:11

SungJinKang


1 Answers

With SFINAE you can enable/disable a method of a class when the condition tested is related to a template parameter of the method itself. Doesn't works testing a template parameter of the class.

You can solve the problem passing through a method template parameter that is defaulted with the type of the class/struct template parameter.

For example

#include <iostream>
#include <type_traits>

template <typename T>
struct foo
 {
   template <typename U = T,
             std::enable_if_t<std::is_signed_v<U>, bool> = true>
   constexpr std::size_t bar ()
    { return sizeof(T); }
 };

int main() 
 {
   foo<signed int>   fs;
   foo<unsigned int> fu;

   fs.bar(); // compile
   //fu.bar(); // compilation error
 }

The problem of this solution is that you can "hijack" it explicating a template parameter

fu.bar(); // compilation error
fu.bar<int>(); // compile 

To avoid the hijacking risk, you can (other solutions are possible but this is my preferred) add a non-type variadic template parameter before U

// .......VVVVVVVV  add this to avoid the hijacking problem
template <int ...,
          typename U = T,
          std::enable_if_t<std::is_signed_v<U>, bool> = true>
constexpr std::size_t bar ()
 { return sizeof(T); }

// ...

fu.bar(); // compilation error
fu.bar<int>(); // compilation error
fu.bar<1, 2, 3, int>(); // compilation error
like image 75
max66 Avatar answered Nov 03 '25 22:11

max66



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!