C++ неявное шаблонное инстанцирование

Я второй "хвост-f" в cygwin. Я предполагаю, что Хвост для Win32 выполнит то же самое.

7
задан 4 revs 19 November 2009 в 07:33
поделиться

5 ответов

Простой способ исправить это - использовать boost :: shared_ptr > вместо ссылки.

1
ответ дан 7 December 2019 в 05:24
поделиться

Возможно, вам стоит использовать const . ?

template <class T>
void Scale(const MatrixBase<T> &A, const T &scale_factor);
0
ответ дан 7 December 2019 в 05:24
поделиться

вы ограничиваете тип первого аргумента Scale, но вы можете позволить компилятору самостоятельно определить, какой тип будет подходящим, например:

template <class M,class T>
void Scale(M A, const T &scale_factor);
0
ответ дан 7 December 2019 в 05:24
поделиться

Не используйте ссылки, передавайте по значению.

Пусть copy elision выполнит оптимизацию за вас, если необходимо.

0
ответ дан 7 December 2019 в 05:24
поделиться

Это не имеет ничего общего с шаблонами. Ваш пример

Scale(Diagonal(A), 2.0);

может быть обобщен до

f(g(v),c);

. В C ++ 03 для этого требуется, чтобы первый параметр в f () передавался либо для каждой копии, либо для ссылки const . Причина в том, что g () возвращает временное r-значение. Однако rvalue привязывается только к const ссылкам, но не к неконстантным ссылкам. Это не зависит от того, задействованы ли шаблоны, SFINAE, TMP или что-то еще. Таков язык (в настоящее время).

Также есть объяснение: если g () возвращает временное значение, и f () изменяет это временное, тогда никто не имеет возможности «увидеть» измененное временное. Таким образом, изменение сделано напрасно, и, скорее всего, все это является ошибкой.

Насколько я понял вас, в вашем случае результат g () является временным, который представляет собой вид на какой-то другой объект ( v ), поэтому его изменение приведет к изменению против . Но если это так, то в текущем C ++ результат g () должен быть либо const (чтобы его можно было привязать к ссылке const , либо он должен быть скопирован. Поскольку const для меня "пахнет" неправильно, то сделать это представление дешевым для копирования, вероятно, было бы лучшим решением.

Однако это еще не все. C ++ 1x представит то, что называется ссылками rvalue. То, что мы знаем как " поэтому вызов f с lvalue неоднозначен и приводит к ошибке времени компиляции.

Однако что не так с перегрузкой для DiagonalView :

template <class T>
void Scale(MatrixBase<T> &matrix, const T &scale_factor);

template <class T>
void Scale(DiagonalView<T> view, const T &scale_factor);

Что-то мне не хватает?


Другое редактирование :

Тогда мне понадобится смехотворно большое количество перегрузок, так как в настоящее время существует более 5 представлений и несколько десятков функций, таких как Масштаб.

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

template<bool B>
struct boolean { enum { result = B }; };

template< typename T >
class some_matrix {
  public:
    typedef boolean<false> is_view;
  // ...
};

template< typename T >
class some_view {
  public:
    typedef boolean<true> is_view;
  // ...
};

namespace detail {
  template< template<typename> class Matrix, typename T >
  void Scale(Matrix<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a matrix*/
  }
  template< template<typename> class Matrix, typename T >
  void Scale(View<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a view */
  }
}

template< template<typename> class Matrix, typename T >
inline void Scale(Matrix<T>& matrix, const T& scale_factor)
{
  detail::Scale( matrix, scale_factor, typename Matrix<T>::is_view() );
}

Эта конкретная установка / группировка может не совсем соответствовать вашим потребностям, но вы можете настроить что-то подобное таким образом, который подходит вам.

что не так с перегрузкой для DiagonalView :

template <class T>
void Scale(MatrixBase<T> &matrix, const T &scale_factor);

template <class T>
void Scale(DiagonalView<T> view, const T &scale_factor);

Что-то мне не хватает?


Другое редактирование :

Тогда мне понадобится смехотворно большое количество перегрузок, так как в настоящее время существует более 5 представлений и несколько десятков функций, таких как Масштаб.

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

template<bool B>
struct boolean { enum { result = B }; };

template< typename T >
class some_matrix {
  public:
    typedef boolean<false> is_view;
  // ...
};

template< typename T >
class some_view {
  public:
    typedef boolean<true> is_view;
  // ...
};

namespace detail {
  template< template<typename> class Matrix, typename T >
  void Scale(Matrix<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a matrix*/
  }
  template< template<typename> class Matrix, typename T >
  void Scale(View<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a view */
  }
}

template< template<typename> class Matrix, typename T >
inline void Scale(Matrix<T>& matrix, const T& scale_factor)
{
  detail::Scale( matrix, scale_factor, typename Matrix<T>::is_view() );
}

Эта конкретная установка / группировка может не совсем соответствовать вашим потребностям, но вы можете настроить что-то подобное таким образом, который подходит для вас.

что не так с перегрузкой для DiagonalView :

template <class T>
void Scale(MatrixBase<T> &matrix, const T &scale_factor);

template <class T>
void Scale(DiagonalView<T> view, const T &scale_factor);

Что-то мне не хватает?


Другое редактирование :

Тогда мне понадобится смехотворно большое количество перегрузок, так как в настоящее время существует более 5 представлений и несколько десятков функций, таких как Масштаб.

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

template<bool B>
struct boolean { enum { result = B }; };

template< typename T >
class some_matrix {
  public:
    typedef boolean<false> is_view;
  // ...
};

template< typename T >
class some_view {
  public:
    typedef boolean<true> is_view;
  // ...
};

namespace detail {
  template< template<typename> class Matrix, typename T >
  void Scale(Matrix<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a matrix*/
  }
  template< template<typename> class Matrix, typename T >
  void Scale(View<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a view */
  }
}

template< template<typename> class Matrix, typename T >
inline void Scale(Matrix<T>& matrix, const T& scale_factor)
{
  detail::Scale( matrix, scale_factor, typename Matrix<T>::is_view() );
}

Эта конкретная установка / группировка может не совсем соответствовать вашим потребностям, но вы можете настроить что-то подобное таким образом, который подходит вам.

поскольку в настоящее время существует более 5 представлений и несколько десятков функций, таких как Scale.

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

template<bool B>
struct boolean { enum { result = B }; };

template< typename T >
class some_matrix {
  public:
    typedef boolean<false> is_view;
  // ...
};

template< typename T >
class some_view {
  public:
    typedef boolean<true> is_view;
  // ...
};

namespace detail {
  template< template<typename> class Matrix, typename T >
  void Scale(Matrix<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a matrix*/
  }
  template< template<typename> class Matrix, typename T >
  void Scale(View<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a view */
  }
}

template< template<typename> class Matrix, typename T >
inline void Scale(Matrix<T>& matrix, const T& scale_factor)
{
  detail::Scale( matrix, scale_factor, typename Matrix<T>::is_view() );
}

Эта конкретная установка / группировка может не совсем соответствовать вашим потребностям, но вы можете настроить что-то подобное таким образом, который подходит для вас.

поскольку в настоящее время существует более 5 представлений и несколько десятков функций, таких как Scale.

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

template<bool B>
struct boolean { enum { result = B }; };

template< typename T >
class some_matrix {
  public:
    typedef boolean<false> is_view;
  // ...
};

template< typename T >
class some_view {
  public:
    typedef boolean<true> is_view;
  // ...
};

namespace detail {
  template< template<typename> class Matrix, typename T >
  void Scale(Matrix<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a matrix*/
  }
  template< template<typename> class Matrix, typename T >
  void Scale(View<T>& matrix, const T& scale_factor, boolean<true>)
  {
    /* scaling a view */
  }
}

template< template<typename> class Matrix, typename T >
inline void Scale(Matrix<T>& matrix, const T& scale_factor)
{
  detail::Scale( matrix, scale_factor, typename Matrix<T>::is_view() );
}

Эта конкретная установка / группировка может не совсем соответствовать вашим потребностям, но вы можете настроить что-то подобное таким образом, который подходит вам.

7
ответ дан 7 December 2019 в 05:24
поделиться
Другие вопросы по тегам:

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