Шаблонные операторы C ++ и дополнительные аргументы шаблона

0

Я создал класс Vector, который принимает количество элементов и тип элемента в качестве аргументов шаблона.

template<int n, class T>
class Vector
{
    public:
        T data[n];

        Vector()
        : data{}
        {
        }

        Vector(T const value)
        {
            std::fill_n(data, n, value);
        }

        template<class ...U, typename std::enable_if<sizeof...(U) == n, int>::type = 0>
        Vector(U &&...u)
        : data{std::forward<U>(u)...}
        {
        }

        T& operator[](int const index)
        {
            return data[index];
        }

        template<class U>
        operator Vector<n, U>()
        {
            Vector<n, U> out;

            std::copy_n(data, n, out.data);

            return out;
        } 
};

Я хочу иметь операторов для класса, но для того, чтобы они могли делать конверсии между векторами с разными типами элементов, они должны быть объявлены и определены внутри тела класса. Но я также хочу иметь 3 специализированных шаблонных класса для Vector 2, 3 и 4. Так как я не хочу писать все операторы 4 раза, один раз внутри каждого класса класса. Могу ли я просто использовать этот оператор с дополнительным аргументом шаблона для типа элемента вектора правой стороны?

template<int n, class T, class U>
inline Vector<n, T>& operator+=(Vector<n, T> &lhs, Vector<n, U> const &rhs)
{
    for(int i = 0; i < n; ++i)
    {
        lhs.data[i] += rhs.data[i];
    }

    return lhs;
}

Вероятно, есть причина, по которой люди используют операторы-друзья внутри класса вместо того, чтобы делать это таким образом, но, похоже, до сих пор я не заметил чего-то?

Теги:
class
templates
operator-overloading

1 ответ

0
Лучший ответ

Здесь нет ничего, кроме суммы частей. "friend" используется для предоставления доступа к операторам, не относящимся к публичным членам, которые, возможно, захотят использовать, и помещая определение внутри класса сохраняет при вводе (и неявно делает их встроенными, избегая проблем с правилами определения одного определения). Если вы собираете класс, вы можете начать вводить определение оператора "friend...", даже не замедляя думать о том, должен ли он быть другом. Некоторым людям также может нравиться наличие операторов, перечисленных внутри класса, - это упрощает их просмотр, когда кто-то просматривает класс, чтобы увидеть, какие функции доступны, но программисты обычно привыкают искать операторов после класса в любом случае....

Если ваш код работает, все хорошо.

  • 0
    «друг» делает больше, чем это. Мой вопрос похож на stackoverflow.com/questions/8890051/… . Операторская функция должна иметь возможность добавлять вектор чисел с плавающей точкой и вектор целых чисел. Но вывод аргумента шаблона происходит до неявного преобразования типов. Вместо того, чтобы использовать решение из этого вопроса, я создал этот обходной путь. Мне интересно, если мой обходной путь вызовет какие-либо проблемы, которые не возникли бы, если бы я использовал решение из этого вопроса.
  • 0
    Этот ответ не иллюстрирует необходимость в другом, о котором вы говорите - например, когда элемент value стал общедоступным, а шаблон с двумя параметрами, охватывающий общий случай сложения, следующий код работает просто отлично: ideone.com/0hMp83 - это очевидный способ сделать это, и действительно - разве это не то, о чем вы спрашиваете в своем вопросе? - Я бы не назвал это «обходным путем».
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню