Есть ли способ подавить средство форматирования диапазона fmt для определяемого пользователем класса?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Есть ли способ подавить средство форматирования диапазона fmt для определяемого пользователем класса?

Сообщение Anonymous »

У меня есть простой класс с методом tostring():

Код: Выделить всё

class MyClass {
public:

std::string tostring() const;

static iterator begin();
static iterator end();
};
Хотя сейчас я использую библиотеку fmt, этот код перенесен из кода, который этого не делал, поэтому многие устаревшие классы реализуют метод tostring(), и у меня есть шаблон, который будет генерировать fmt::formatter для любого класса, имеющего этот метод. Он работает нормально.
Однако этот конкретный класс также имеет функции начала/конца. Однако они статичны (этот класс похож на перечисление, и вы можете перебирать все возможные значения) и не должны иметь ничего общего с форматированием.
Все было хорошо, пока мне не понадобилось включить fmt/ranges.h для какого-то другого кода. Проблема в том, что существует средство форматирования диапазона, которое видит функции начала/конца и хочет отформатировать класс как диапазон. Теперь, если я попытаюсь отформатировать класс, я получу неоднозначный экземпляр средства форматирования (один для шаблона, который я хочу использовать, и один для средства форматирования диапазона).
Есть ли способ заставить средство форматирования диапазона игнорировать этот класс?
Полный пример:

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 
// #include 

// Create formatter for any class that has a tostring() method

template 
struct has_tostring_member {
private:
template 
static std::true_type  test( decltype(&U::tostring) );
template 
static std::false_type test(...);
public:
using result = decltype(test(0) );
static constexpr bool  value = result::value;
};

template 
struct  fmt::formatter
: formatter {
template 
auto
format( const T& e, FormatContext& ctx )
{
return formatter::format( e.tostring(), ctx );
}
};

class MyClass
{
public:
explicit MyClass(int i) : value(i) {}

std::string tostring() const { return std::to_string(value); }

static auto begin() { return std::begin(static_data); }
static auto end() { return std::end(static_data); }

private:
int  value;
static const std::vector static_data;
};

const std::vector MyClass::static_data{ "a", "b", "c" };

int main(void) {
MyClass c{10};

fmt::print("c is {}\n", c);

return 0;
}
Если у меня есть полная специализация fmt::formatter для MyClass, то нет никакой двусмысленности, но если я использую частичную специализацию, как в примере, то раскомментирование «#include » приведет к неоднозначному созданию экземпляра шаблона.>

Подробнее здесь: https://stackoverflow.com/questions/671 ... ined-class
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»