Ссылка / значение параметра аргумента шаблона C ++ - PullRequest
2 голосов
/ 10 августа 2010

Я не уверен, имеет ли название смысл.

позвольте мне объяснить, что я хочу сделать:

У меня есть конструктор шаблонов, аргумент обычно должен быть ссылочным, но в некоторых случаях может иметь значение. В конечном итоге я хотел бы иметь что-то вроде:

matrix_adapter(typename adaptable<T,A>::type);

, где adaptable<T,A>::type может быть значением или ссылочной защитой для типа A. Я не могу этого сделать (создание экземпляра шаблона не происходит) и не знаю, почему.

Сейчас мое решение - включить / отключить конструктор, используя Sfinae:

matrix_adapter(A a, typename adaptable<T,A>::pass_by_value = 0)

Однако для этого требуются два одинаковых конструктора.

Можно ли сделать это с помощью одного универсального конструктора?

больше код:

template<typename T>
struct adaptable<T, boost::detail::multi_array::const_sub_array<T, 2, const T*> >
{
    typedef void* pass_by_value;
    typedef boost::detail::multi_array::const_sub_array<T, 2, const T*> type;
    static size_t size1(const type &A) { return A.shape()[0]; }
    static size_t size2(const type &A) { return A.shape()[1]; }
    static const T* data(const type &A) { return A.origin(); }
};

template<typename T, class L = ublas::column_major>
struct matrix_adapter
    : ublas::matrix<T, L, ublas::array_adaptor<T> >
{
    typedef ublas::array_adaptor<T> array_type;
    typedef ublas::matrix<T, L, array_type> base;
    matrix_adapter(size_t size1, size_t size2, T *data)
        : base(size1, size2, array_type(size1*size2, pointer()))
    {
        initialize(data);
    }

    template<class A>
    matrix_adapter(A a, typename adaptable<T,A>::pass_by_value = 0)
        : base(adaptable<T,A>::size1(a),
               adaptable<T,A>::size2(a),
               array_type(adaptable<T,A>::size1(a)*
                          adaptable<T,A>::size2(a),
                          pointer()))
    {
        initialize(adaptable<T,A>::data(a));
    }

    template<class A>
    matrix_adapter(A &a)
        : base(adaptable<T,A>::size1(a),
               adaptable<T,A>::size2(a),
               array_type(adaptable<T,A>::size1(a)*
                          adaptable<T,A>::size2(a),
                          pointer()))
    {
        initialize(adaptable<T,A>::data(a));
    }

1 Ответ

1 голос
/ 11 августа 2010

Ваш конструктор сам является шаблоном, но с сигнатурой matrix_adapter(typename adaptable<T,A>::type) компилятор не может определить тип A из вызова.

Используя SFINAE, вы разрешаете компилятору выводить Aиз первого аргумента конструктора, а затем второй аргумент предотвращает рассмотрение того или другого в наборе перегрузки.

Я не верю, что можно удалить любой конструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...