Я совсем новичок в области программирования шаблонов на c++.

Я понимаю, что я могу специализировать шаблоны функций, например, в моем случае шаблон функции toJson, который я хочу использовать с помощью ADL.

Например,

template
Json::Value toJson(const T&);

где Json::Value предоставляется библиотекой JsonCPP-Library.

Сейчас я могу специализировать это для "нормальных" типов, таких как этот:

template<>
Json::Value toJson(const MyClass&)

Здорово.

Кроме того, у меня есть тип KalmanFilter<3, 3, 3, double> (очевидно, он полностью параметризован), который в свою очередь имеет несколько Eigen3-матриц в качестве типа, размерность которых определяется на основе аргументов интегрального шаблона в KalmanFilter. Я хотел бы специализировать toJson следующим образом:

template<>
Json::Value toJson>(const KalmanFilter ...)

Может быть, есть другой способ добиться этого (например, Eigen перегружает оператор std::ostream<< обобщенно для всех своих типов).

Или мне нужно использовать по-другому объявленный toJson, например

template
Json::Value toJson(const KalmanFilter&);

?

deets

Ответов: 2

Ответы (2)

Я бы решил эту проблему, используя шаблон struct и специализируя его, вместо специализации шаблона функции, из-за потенциальных недостатков.

// Hide implementation details in `impl` namespace.
namespace impl
{
    // Forward-declaration of helper converter struct.
    template
    struct json_converter;

    // Example specialization: `int`.
    template<>
    struct json_converter
    {
        Json::Value to_json(const int&) 
        { 
            // 
        }
    };

    // Example specialization: `KalmanFilter`.        
    template
    struct json_converter>
    {
        Json::Value to_json(const KalmanFilter&) 
        { 
            // 
        }
    };
}

// Convenient user-interface function, deduces `T`.
template
auto to_json(const T& x)
{
    // Instantiate a temporary `json_converter` and call `to_json`.
    return impl::json_converter>{}.to_json(x);
}

Использование:

KalmanFilter<4, 4, 4, double> kf{/* ... */};
auto result = to_json(kf);

Или мне нужно использовать по-другому объявленный toJson, например

template
Json::Value toJson(const KalmanFilter&);

?

Да, это именно то, что вам нужно.

Вы сами себя запутали, ввязавшись в специализацию шаблонов функций. Нет абсолютно никаких причин использовать здесь специализацию шаблона функции. Если вам нужны преобразования для других типов, просто добавьте их таким же образом:

 template
 Json::Value toJson(const OtherFilter&);

Если у вас есть разные типы в разных пространствах имен, то использование одного шаблона функции с несколькими специализациями не будет работать с ADL. Каждая функция toJson должна находиться в пространстве имен своего типа параметра. Не говоря уже о том, что вы потенциально можете быть удивлены тем, какую специализацию компилятор на самом деле решит использовать. Обычное разрешение перегрузки удивляет меньше.

2022 WebDevInsider