簡體   English   中英

僅為專用模板類定義轉換運算符

[英]Defining conversion operator for specialized template class only

我想為矩陣<1、1>定義為浮點型的轉換。 我很難弄清楚如何真正定義它。 如果我將其設為全局函數

template<typename T>
inline operator T(const matrix<T, 1, 1> &m){ return m(0, 0); }

我得到“運算符..必須是非靜態成員函數”

我當然可以將其定義為通用矩陣模板的成員,但隨后將為所有矩陣定義它-這不是我想要的。 我希望僅針對1x1矩陣的特定情況進行定義。

您必須為此專門設置一個類,例如:

template <typename Base, typename T, std::size_t W, std::size_t H>
struct MatrixConversion
{ /*Empty*/ };

template <typename Base, typename T> struct MatrixConversion<T, 1u, 1u>
{
    operator const T&() const { return static_cast<const Base&>(*this).m[0][0]; }
};


template <typename T, std::size_t W, std::size_t H>
struct Matrix : MatrixConversion<Matrix<T, W, H>, T, W, H>
{
    // Your code
};

組合加專業化將是最可維護的方法。

您沒有在矩陣模板類中指定維數,因此我假設它可以是可變的。

#include <cstdint>
#include <utility>

//
// forward-declare class template for convenience.
//
template<class T, std::size_t...Dimensions>
struct matrix;

//
// classes to figure out the storage requirements of a multi-dimensional
// matrix
//
template<class T, std::size_t...Dimensions> struct storage;
template<class T, std::size_t N>
  struct storage<T, N>
  {
    using type = T[N];
  };

template<class T, std::size_t...Rest, std::size_t N>
  struct storage<T, N, Rest...>
  {
    using less_dimension_type = typename storage<T, Rest...>::type;
    using type = less_dimension_type[N];
  };


//
// functions for dereferencing multi-dimensional arrays
//
template<class Array, class Arg>
decltype(auto) deref(Array& array, Arg&& arg)
{
  return array[arg];
}

template<class Array, class Arg, class Arg2>
decltype(auto) deref(Array& array, Arg&& arg, Arg2&& arg2)
{
  return array[arg][arg2];
}

template<class Array, class Arg, class...Args>
decltype(auto) deref(Array& array, Arg&& arg, Args&&...args)
{
  return deref(deref(array, arg), std::forward<Args>(args)...);
}

//
// prototype for operations we want to conditionally apply
//
template<class Matrix>
struct matrix_conditional_ops
{
  // in the general case, none
};

//
// compose the matrix class from conditional_ops<>
//    
template<class T, std::size_t...Dimensions>
struct matrix 
  : matrix_conditional_ops<matrix<T, Dimensions...>>
{

    template<class...Dims>
    decltype(auto) at(Dims&&...ds)
    {
      return deref(_data, std::forward<Dims>(ds)...);
    }

    template<class...Dims>
    decltype(auto) at(Dims&&...ds) const
    {
      return deref(_data, std::forward<Dims>(ds)...);
    }

   typename storage<T, Dimensions...>::type _data;
};

//
// define the condition operations for the <T, 1, 1> case
//    
template<class T>
  struct matrix_conditional_ops<matrix<T, 1, 1>>
  {
    using matrix_type = matrix<T, 1, 1>;

    operator T const() { return static_cast<matrix_type const&>(*this).at(0,0); }
  };


int main()
{
  matrix<double, 1, 1> m11;

  m11.at(0,0) = 6.0;
  double d = m11;

  matrix<double, 2, 2> m22;
  // compile error:
//  double d2 = m22;

  // bonus points:

  matrix<double, 3, 5, 2, 7> mxx;
  mxx.at(2, 4, 1, 6) = 4.3;  // probably needs some compile-time checking...

}

有人可能想檢查一下我的邏輯以進行數組打包/解引用...

我認為JarodRichard已經為您提供了最佳答案,它們可以很好地擴展到具有各種限制的任何數量的運營商。

但是,如果您無力重新設計課程,或者您只需要一個快速而骯臟的opertor T() ,則opertor T()以下問題:

template<typename T, std::size_t N1, std::size_t N2>
struct Matrix
{
    T m[N1][N1];

    operator T()
    {
        static_assert(N1 == 1 && N2 == 1, "Only applicable to scalars");
        return m[0][0];
    }
};

這是住這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM