Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用常量引用作为模板参数?_C++_C++11_Templates_Vector - Fatal编程技术网

C++ 如何使用常量引用作为模板参数?

C++ 如何使用常量引用作为模板参数?,c++,c++11,templates,vector,C++,C++11,Templates,Vector,我试图实现一种矩阵包装器,它将容器的容器作为模板参数 但我在尝试构造常量引用的矩阵包装器时出错。这段代码似乎使用了一个非引用、非指针、非常量参数,我想对这两种情况使用相同的代码。即使我会有另一个指针模板专门化 当我试图编译此代码时,会出现以下错误: >c:\users\emedeiros\source\repos\test\test\test.cpp(240): error C2079: 'matrix' uses undefined class 'matrix_wrapper<co

我试图实现一种矩阵包装器,它将容器的容器作为模板参数

但我在尝试构造常量引用的矩阵包装器时出错。这段代码似乎使用了一个非引用、非指针、非常量参数,我想对这两种情况使用相同的代码。即使我会有另一个指针模板专门化

当我试图编译此代码时,会出现以下错误:

>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

>c:\users\emedeiros\source\repos\test\test\test.cpp(240):错误C2079:“matrix”使用未定义的类“matrix\u wrapper”
1> 与
1>        [
1> _Ty=double
1>        ]
1> c:\users\emedeiros\source\repos\test\test\test.cpp(240):错误C2440:“初始化”:无法从“const std::vector”转换为“int”
1> 与
1>        [
1> _Ty=double
1>        ]
1> c:\users\emedeiros\source\repos\test\test\test.cpp(240):注意:没有可以执行此转换的用户定义的转换运算符,或者无法调用该运算符
1.
下面您将找到类定义和一个函数,该函数将尝试创建一个matrix_包装器

#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);
}

#包括
模板
类矩阵包装器;
模板
类矩阵包装器,A2>>
{
公众:
typedef typename boost::call_traits::value_type value_type;
typedef typename boost::call_traits::param_type param_type;
typedef typename boost::call_traits::reference;
typedef Cont1矢量_type;
typedef typename boost::call_traits::reference vector_type_ref;
typedef typename boost::call_traits::const_参考向量_type_const_ref;
typedef T数据类型;
矩阵_包装器(参考数据):m_数据(数据){}
内联向量类型常数参考运算符[](大小i)常数
{
返回m_数据[i];
}
内联向量类型参考运算符[](大小i)
{
返回m_数据[i];
}
内联引用数据()
{
返回m_数据;
}
受保护的:
参考m_数据;
};
无效测试(常数标准::向量和数据)
{
矩阵_包装矩阵(数据);
}
int main()
{
std::vector v(10,std::vector(10,1));
试验(五);
}

我需要更改什么才能使用常量引用作为参数?

我不会直接回答您的问题,但我敢猜您真正需要听到的是什么:)

首先,将引用作为模板类型通常不是一个好主意。如果您想制作一个包装器,在类中包装一个引用是有意义的,但最好将模板参数类型保持为值类型,而不是引用类型。话虽如此,如果您确实希望将引用类型作为参数,那么您可能需要使用
std::decay

然后,我看到这里有部分模板专门化。从你发布的代码来看,不清楚你是否真的需要它。我个人喜欢把事情简单化,所以我建议你不用它也行。在这种情况下,只需在一个且唯一的类型
T
上对类进行参数化

请注意,不要声明函数
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);
}
#包括
模板
类矩阵包装器
{
公众:
使用reference=const T&;
使用vector_type_ref=typename T::reference;
使用vector_type_const_ref=typename T::const_reference;
矩阵_包装器(参考数据):m_数据(数据){}
向量类型常数参考运算符[](大小i)常数
{
返回m_数据[i];
}
//顺便说一句,这不会为非常量对象编译,因为您存储了常量
//引用容器,但这是另一个故事
向量类型参考运算符[](大小i)
{
返回m_数据[i];
}
参考数据()
{
返回m_数据;
}
受保护的:
参考m_数据;
};
无效测试(常数标准::向量和数据)
{
矩阵_包装矩阵(数据);
}
int main()
{
std::vector v(10,std::vector(10,1));
试验(五);
}
请参见此处的实时演示:

我看到您在
main()
中将
v
声明为
int
s的
vector
,但在
test()
中接受
vector
double
。我认为这是一个印刷错误,并修复了类型


我完全同意@NathanOliver关于1D/2D的观点,但这又是另一回事。

FWIW你真的不想对矩阵使用2D向量吗。它们没有保证的缓存局部性,因此在计算量大的代码中,它们可能成为真正的性能瓶颈。不幸的是,由于一些限制,这里我不得不使用std::vector作为该矩阵的基础。这很好,但只使用一维。二维向量可以由两个维度相乘的一维向量替换。