Выражение SFINAE без enable_if? - PullRequest
       8

Выражение SFINAE без enable_if?

0 голосов
/ 20 сентября 2018

Я написал программу следующим образом

#include <iostream>
#include <vector>
#include <string>

using namespace std;

template <typename T>
auto serialize(const T& t) -> decltype(to_string(t))
{
    return to_string(t);
}

template <typename T>
auto serialize(const T& t) -> string
{
    return "<object>";
}


int main()
{
    cout<<serialize(4)<<endl;
    cout<<serialize(vector<int>())<<endl;
    return 0;
}

Когда тип программы поддерживается to_string, я хотел бы использовать первый шаблон.Но если нет поддержки типа to_string, то я хотел бы использовать второй шаблон.

Мне бы хотелось увидеть следующие результаты

4
<object>

Но когда я компилируюпрограмма, я получаю следующую ошибку

main.cpp: In function ‘int main()’:
main.cpp:22:19: error: call of overloaded ‘serialize(int)’ is ambiguous
  cout<<serialize(4)<<endl;
                   ^
compilation terminated due to -Wfatal-errors.

И я на самом деле не могу винить компилятор.Как я могу устранить эту двусмысленность, не используя enable_if или enable_if_t.Сохранение программы простой с помощью SFINAE с выражением.На самом деле, decltype(to_string(t)) ясно.Но типы не имеют операторов not или otherwise.

1 Ответ

0 голосов
/ 20 сентября 2018

Вы могли бы расставить приоритеты своих перегрузок с дополнительным аргументом:

template <std::size_t N> struct OverloadPriority : OverloadPriority<N -1> {};
template <> struct OverloadPriority<0> {};

template <typename T>
auto serialize_impl(const T& t, OverloadPriority<1>) -> decltype(to_string(t))
{
    return to_string(t);
}

template <typename T>
auto serialize_impl(const T& t, OverloadPriority<0>) -> std::string
{
    return "<object>";
}

template <typename T>
decltype(auto) serialize(const T& t)
{
    return serialize_impl(t, OverloadPriority<1>{});
}

Демо

...