从嵌套模板中删除常量

Remove const from nested template

本文关键字:删除 常量 嵌套      更新时间:2023-10-16

我有一个模板化类,它有自己的存储,但也可以用来使用指向数组中某个位置的指针来"查看"(甚至修改)更大的数组。查看更大的数组是使用以下方法完成的(请参阅下面的完整示例):

Tensor<double> t;
t.view(&array[i]);

当数组标记为const可以使用以下内容

Tensor<const double> t;
t.view(&array[i]);

我的问题是现在:

我想为Tensor<...>编写一个带有一个模板参数的函数,该函数可用于映射const数组并修改映射的副本。如何从"嵌套模板"中删除const?或者,如果无法做到这一点,如何在不将其标记为模板const的情况下使用地图?

请注意,我目前没有从Tensor<const double>转换为Tensor<double>


显示此行为的一个简单、完整的示例是

#include <iostream>
#include <vector>
template<class T>
class Tensor
{
private:
T m_container[4];
T *m_data;
public:
// constructor
Tensor() { m_data = &m_container[0];};
// copy constructor
Tensor(const Tensor& other)
{
for ( auto i = 0 ; i < 4 ; ++i )
m_container[i] = other[i];
m_data = &m_container[0];
}
// index operator
T& operator[](size_t i) { return m_data[i]; }
const T& operator[](size_t i) const { return m_data[i]; }
// point to external object
void view(T *data) { m_data = data; }
};

template<class T>
T someOperation(std::vector<double> &input, size_t i)
{
T t;
t.view(&input[i*4]);
// ... some code that uses "t" but does not modify it
T s = t;
return s;
}

int main()
{
std::vector<double> matrix = { 1., 2., 3., 4., 11., 12., 13., 14. };
Tensor<double> tensor = someOperation<Tensor<double>>(matrix, 1);
return 0;
}

例如使用clang++ -std=c++14 so.cpp编译。

现在我想将函数的签名更改为

template<class T>
T someOperation(const std::vector<double> &input, size_t i)

上述函数可以使用

someOperation<Tensor<const double>>(...)

但显然我不能再改变s了。我该如何解决这个问题?

考虑 std::remove_const:

template<typename T>
void f(T& t);
double const d = 1.0;
f(d);
template<typename T>
void f(T& t)
{
T ct = t;
//ct += 1.0; // refuses to compile!
typename std::remove_const<T>::type nct = t;
nct += 1.0;  // fine...
}

编辑:好的,只有一半的真相...

通过提供的示例,事情变得更加复杂,因为您需要交换内部模板类型......

这可以通过模板模板函数来完成:

template<template < class > class T, typename V>
auto someOperation(std::vector<double>& input, size_t i)
{
T<V> t;
t.view(&input[i*4]);
T<typename std::remove_const<V>::type> s = t;
return s;
}

但是,这给您带来了很多麻烦:

  1. 常量成员不能在构造函数体中初始化,所以你需要:Tensor

    (Tensor const&other) : m_container { 其他[0], 其他[1], 其他[2], 其他[3] }, m_data(m_container) { }
  2. Tensor<double>Tensor<double const>是完全不同的类型,因此它们需要彼此构造:Tensor

    (Tensor::type> const& other); Tensor(Tensor模板<类型名TT>Tensor(Tensorconst& other);
    这甚至允许您从例如整数张量初始化例如双张量 - 如果需要与否,决定您...