Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SFINAE fallback when a function does not exist

I'm currently trying to implement a toString function which calls .toString() or std::to_string() depending on which is available for the deduced type

So far I have this working snippet:

#include <iostream>
#include <string>

template <class T>
auto toString(const T& obj)
        -> decltype(obj.toString(), std::string())
{
  return obj.toString();
}

template <class T>
auto toString(const T& obj)
        -> decltype(std::to_string(obj), std::string())
{
  return std::to_string(obj);
}

template <class T>
auto toString(const T& obj)
        -> decltype(std::string(obj))
{
  return std::string(obj);
}

class Foo{
public:
  std::string toString() const {
    return "Hello";
  }
};

int main()
{
  Foo bar;
  std::cout << toString(bar);
  std::cout << toString(5);
  std::cout << toString("Hello const char*");
}

Now I want to insert a static_assert when no overload from those above is viable, because the default GCC error message for older GCC versions is not very informative.

How can I check if neither .toString() nor std::to_string() are possible for T?

So far I found no way to check if something is not present, only the other way around. I hope someone has an idea how to solve this and thanks for your time.

like image 823
Alexander Weinrauch Avatar asked Dec 02 '22 12:12

Alexander Weinrauch


1 Answers

You need to introduce an overload that is worse than every other that you currently have, and delete it. You don't need to check if neither of the string functions exist that way.

A popular way to do this is to use C style variadic arguments:

std::string toString(...) = delete;
like image 187
Rakete1111 Avatar answered Dec 22 '22 06:12

Rakete1111