簡體   English   中英

如何使用常量引用作為模板參數?

[英]How to use a const reference as template parameter?

我正在嘗試實現一種矩陣包裝器,它將容器的容器作為模板參數。

但是在嘗試構造常量引用的 matrix_wrapper 時出現錯誤。 該代碼似乎適用於非引用、非指針、非 const 參數,我想對這兩種情況使用相同的代碼。 即使我將有另一個針對指針的模板專業化。

當我嘗試編譯此代碼時,出現以下錯誤:

>c:\users\emedeiros\source\repos\test\test\test.cpp(240): error C2079: 'matrix' uses undefined class 'matrix_wrapper<const std::vector<std::vector<double,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>> &>'
1>        with
1>        [
1>            _Ty=double
1>        ]
1>c:\users\emedeiros\source\repos\test\test\test.cpp(240): error C2440: 'initializing': cannot convert from 'const std::vector<std::vector<double,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>>' to 'int'
1>        with
1>        [
1>            _Ty=double
1>        ]
1>c:\users\emedeiros\source\repos\test\test\test.cpp(240): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1

您將在下面找到類定義和一個嘗試創建 matrix_wrapper 的函數。

#include <vector>

template <class T>
class matrix_wrapper;

template <typename T, class A1, class A2, template <typename, typename> class Cont1, template <typename, typename> class Cont2>
class matrix_wrapper < Cont2 < Cont1 < T, A1>, A2> >
{
public:
    typedef typename boost::call_traits<Cont2<Cont1<T, A1>, A2>>::value_type value_type;
    typedef typename boost::call_traits<value_type>::param_type param_type;
    typedef typename boost::call_traits<value_type>::reference reference;

    typedef Cont1<T, A1> vector_type;
    typedef typename boost::call_traits<vector_type>::reference vector_type_ref;
    typedef typename boost::call_traits<vector_type>::const_reference vector_type_const_ref;
    typedef T data_type;

    matrix_wrapper(reference data) : m_data(data) {}

    inline vector_type_const_ref operator[](size_t i) const
    {
        return m_data[i];
    }

    inline vector_type_ref operator[](size_t i)
    {
        return m_data[i];
    }

    inline reference data()
    {
        return m_data;
    }

protected:
    reference m_data;
};


void test(const std::vector<std::vector<double>>& data)
{
    matrix_wrapper<const std::vector<std::vector<double>>&> matrix(data);
}


int main()
{
    std::vector<std::vector<int>> v(10, std::vector<int>(10, 1));
    test(v);
}

我必須更改什么才能使用常量引用作為參數?

我不會直接回答你的問題,但我敢猜測你真正需要聽到什么:)

首先,將引用作為模板類型通常不是一個好主意。 如果你想創建一個包裝器,在你的類中的包裝器上有一個引用是有意義的,但最好將模板參數類型保持為值類型,而不是引用類型。 話雖如此,如果您真的確定要將引用類型作為參數,則可能需要使用std::decay

然后,我看到你在這里有部分模板專業化。 從您發布的代碼中不清楚您是否真的需要它。 我個人喜歡讓事情保持簡單,所以我建議你沒有它也很好。 在這種情況下,只需在一個且僅鍵入T上參數化您的類。

作為旁注,不要聲明您的函數inline 編譯器最了解你。 無論如何,在類范圍內定義的方法默認是inline的。 忘記inline意味着“請使此代碼更快”。 這實際上意味着“此符號可能出現在多個翻譯單元中,請為我選擇一個定義”。

最后,boost 是一個很棒的庫,但我看不出你在這里需要它。 所有標准容器都在其中提供了所有必要的類型別名,只需詢問即可。

這是根據我的評論簡化的編譯代碼:

#include <vector>

template <class T>
class matrix_wrapper
{
public:
  using reference = const T&;
  using vector_type_ref = typename T::reference;
  using vector_type_const_ref = typename T::const_reference;

  matrix_wrapper(reference data) : m_data(data) {}

  vector_type_const_ref operator[](size_t i) const
  {
    return m_data[i];
  }
  // BTW this won't compile for non-const objects, since you store a const
  // reference to the container, but that's a different story
  vector_type_ref operator[](size_t i) 
  {
    return m_data[i];
  }
  reference data()
  {
    return m_data;
  }

protected:
    reference m_data;
};


void test(const std::vector<std::vector<int>>& data)
{
    matrix_wrapper<std::vector<std::vector<int>>> matrix(data);
}

int main()
{
    std::vector<std::vector<int>> v(10, std::vector<int>(10, 1));
    test(v);
}

在此處查看現場演示: https : //wandbox.org/permlink/tmemloS6wCHZlhNY

我看到您在main()中將v聲明為intvector ,但您在test()接受了doublevector 我認為這是印刷錯誤並修復了類型。

我完全同意@NathanOliver 關於 1D/2D 的事情,但這又是一個不同的故事。

暫無
暫無

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

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