Я второй "хвост-f" в cygwin. Я предполагаю, что Хвост для Win32 выполнит то же самое.
Простой способ исправить это - использовать boost :: shared_ptr
вместо ссылки.
Возможно, вам стоит использовать const
. ?
template <class T>
void Scale(const MatrixBase<T> &A, const T &scale_factor);
вы ограничиваете тип первого аргумента Scale, но вы можете позволить компилятору самостоятельно определить, какой тип будет подходящим, например:
template <class M,class T>
void Scale(M A, const T &scale_factor);
Не используйте ссылки, передавайте по значению.
Пусть copy elision выполнит оптимизацию за вас, если необходимо.
Это не имеет ничего общего с шаблонами. Ваш пример
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() );
}
Эта конкретная установка / группировка может не совсем соответствовать вашим потребностям, но вы можете настроить что-то подобное таким образом, который подходит вам.