Шаблонное преобразование типа C++ с производными

Я искал способ сделать это в течение достаточно долгого времени. Интересно, как трудно это должно было бы создать плагин vs.net, чтобы сделать это для Вас.

5
задан tomzx 30 September 2009 в 21:22
поделиться

4 ответа

Невозможно статическое приведение, так как это несовместимые типы. Иногда вместо этого можно создать оператор для приведения типа.

#include <iostream>

class A { };

class B : public A { };


template<typename T>
struct holder {
    T* value;

    holder ( T*value ) : value ( value ) { }

    template < typename U > // class T : public U
    operator holder<U> () const
    {
        return holder<U>( value );
    }
};


int main ()
{
    using namespace std;

    B   b;

    holder<B>   hb ( &b );
    holder<A>   ha  = hb;

    cout << boolalpha;

    cout << ( hb.value == ha.value ) << endl;

    return 0;
}

Является ли это значимой операцией, скорее, зависит от семантики класса шаблона - если aFunction может помещать что-либо в обработчик, вы не можете хотите, чтобы более конкретный объект был изменен. Следовательно, вы каким-то образом копируете, либо с помощью оператора принуждения, либо с помощью конструктора копирования и присваивания шаблона. (принуждение - это меньше кода, но может привести к созданию большего количества объектов, если вы не используете ссылочные параметры)

12
ответ дан 18 December 2019 в 07:10
поделиться

Типы не могут быть преобразованы по умолчанию таким образом (потому что вы можете не захотеть, чтобы объекты делали это). В общем, вы можете использовать два подхода:

Реализовать функцию явного приведения, которая может быть полезна для приведения во время выполнения, например boost shared_ptr dynamic_pointer_cast . В результате вы получите что-то вроде:

template <typename To, typename From>
myclass<To> myclass_cast(const myclass<From>&)
{ /* do a runtime cast, possibly with exceptions */ }

Второй метод - это конструктор преобразования, что хорошо, если он разрешим во время компиляции, если они могут быть преобразованы. Например, если все классы можно преобразовать из шаблонных на Derived в шаблонные на Base, вот конструктор, который будет работать только тогда, когда это истинно (с использованием enable_if и boost :: type_traits):

template <typename To>
class myclass {
  //converting constructor
  template <typename From>
  myclass(const myclass<From>&,
          typename enable_if<boost::type_traits::is_base_of<To, From> >::type* dummy = 0)
  {  }
};
6
ответ дан 18 December 2019 в 07:10
поделиться

Извините, это невозможно. (Ну, если вы не применяете неприятные хаки reinterpret_cast , но вы не хотите этого делать - конечный результат будет не очень приятным).

T и T <Доставлено> не связаны. Компилятор не может это предположить - помните, что вполне возможно, что T был специализирован для Derived, чтобы быть чем-то совершенно другим.

3
ответ дан 18 December 2019 в 07:10
поделиться

Шаблоны в C ++, а также дженерики в C ++. Net не являются ковариантными.

Проверить этот вопрос может дать вам представление об обходном пути.

1
ответ дан 18 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: