0

I'm falling into a problem, so I want to avoid this problem which is: if I provide a class template, I have to ensure that when I enter string it returns false, it worked for primitive data type but for this class template no.

template<class Y>
class Point
{
    Y x, y;
public:
    Point(){}
    Point(Y _x, Y _y):x(_x),y(_y){}
    ~Point(){}

    Point<Y>& operator++()
    {
        ++x;
        ++y;
        return *this;
    }
};
Point<int>Pi;
template< typename, typename = void >
struct is_incrementable : std::false_type { };

template< typename T >
struct is_incrementable<T,std::void_t<decltype(++std::declval<T&>())>> : std::true_type { };

int main()
{
    cout << boolalpha;
    cout << is_incrementable<Point<int>>();
    return 0;
}

how can I resolve that?

1 Answers1

3

You need to apply your is_incrementable to operator++ to make sure you do not define that function when Y is not incrementable. You can do that with SFINAE like

template< typename, typename = void >
struct is_incrementable : std::false_type { };

template< typename T >
struct is_incrementable<T,std::void_t<decltype(++std::declval<T&>())>> : std::true_type { };

template<class Y>
class Point
{
    Y x, y;
public:
    Point(){}
    Point(Y _x, Y _y):x(_x),y(_y){}
    ~Point(){}

    template <typename T = Y, std::enable_if_t<is_incrementable<T>::value, bool> = true>
    //        ^            ^ this is needed as SFINAE only works with the current template parameters
    Point<T>& operator++()
    {
        ++x;
        ++y;
        return *this;
    }
};

and using

int main()
{
    using namespace std;
    cout << boolalpha;
    cout << is_incrementable<Point<int>>() << "\n";
    cout << is_incrementable<Point<string>>();
    return 0;
}

will print

true
false

which you can see in this live example

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • thanks but I got this error: ```Severity Code Description Project File Line Suppression State Error C2903 'is_incrementable': symbol is neither a class template nor a function template Meta_programming``` –  May 18 '20 at 15:26
  • Define `is_incrementable` before class `Point`. – Paul Sanders May 18 '20 at 15:27
  • @Ope If you compile the code as shown [here](http://coliru.stacked-crooked.com/a/f44060ca5f8a78fa) exactly like it is, do you still get the error? – NathanOliver May 18 '20 at 15:27
  • it works, but @PaulSanders is right, I have to define but how can I define it, because it's in seperate file, I have Point.h and main.cpp –  May 18 '20 at 15:29
  • @Ope Include the file that `is_incrementable` is in, in the file that `Point` is defined in. – NathanOliver May 18 '20 at 15:30
  • @Ope Maybe put `is_incrementable` in its own header file? – Paul Sanders May 18 '20 at 15:31
  • @NathanOliver, ```is_incrementable``` is in main.cpp –  May 18 '20 at 15:31
  • @PaulSanders, it cannot be in main.cpp? –  May 18 '20 at 15:31
  • @Ope Put it in it's own header file then. – NathanOliver May 18 '20 at 15:32
  • @NathanOliver, is it always obligatory? –  May 18 '20 at 15:33
  • @Ope It's not oblogatory, but if you want to use `is_incrementable` in other files, then it needs to be in a header file so you can include it where you need it. – NathanOliver May 18 '20 at 15:35
  • @NathanOliver thanks, but there's no way to declare it as a forward declaration in Point.h? –  May 18 '20 at 15:36
  • @Ope No. In order for template code to work, `Point.h` needs to know the definition of `is_incrementable`. Can I ask why you don't want to put `is_incrementable` in a header file? – NathanOliver May 18 '20 at 15:37
  • @NathanOliver, no just I want to gather the maximum of information –  May 18 '20 at 15:38
  • @Ope In that case, you should have a read of this: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – NathanOliver May 18 '20 at 15:39
  • @NathanOliver thank you, I want to ask you, I want to learn the more efficient way of templates and TMP can you suggest me something please? –  May 18 '20 at 15:45
  • @Ope there are good books on the subject listed here: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – NathanOliver May 18 '20 at 15:48