Home > Net >  Avoid conversion from const to non const (typename)
Avoid conversion from const to non const (typename)

Time:06-27

I try to follow these rules:

  1. When Test Iterator is non const, you can only init with a non const
  2. When Test Iterator is const, you can init with a non const and a const

How to respect this, I did a little research with SFINAE but the problem is that I precisely need to say:

When I'm non const you can't accept a const

template<typename Iterator>
class Test
{
   public :

      typedef Iterator it;

      Test() :
         _current(Iterator()) {}

      Test(const Test& x) :
         _current(x.getCurrent()) {}

      template<typename Iter>
      Test(const Test<Iter>& x) :
         _current(x.getCurrent()) {}
      
      ~Test() {}

      it&
      getCurrent() const { return this->_current; }

   private :

      Iterator _current;
};
 
int main() 
{
   Test<const int> test1;
   Test<int> test2(test1);
   return 0;
}

CodePudding user response:

Here is an example of a basic approach (without going full SFINAE), that will give you a compilation error (because of a failed static_assert)

#include <type_traits>

template<typename type_t>
class Test
{
public:
    Test() = default;
    ~Test() = default;

    template<typename rhs_t>
    Test(const Test<rhs_t>& x)
    {
        static_assert(std::is_same_v<type_t, rhs_t>, "types are not compatible");
    }
};

int main()
{
    Test<const int> test1;
    Test<int> test2(test1);
    return 0;
}

CodePudding user response:

You can use std::enable_if and std::is_same as shown below:

template<typename Iterator>
class Test
{
   public :
   //other code 

    template<typename Iter, std::enable_if_t<std::is_same_v<Iterator, Iter>>>
      Test(const Test<Iter>& x) :
         _current(x.getCurrent()) {}
};
int main() 
{
   Test<const int> test1;
  Test<int> test2(test1); //wont work 
   
   Test<const int> test3(test1); //works 
   return 0;
}

Demo

  • Related