从嵌套模板中删除const

时间:2018-03-26 14:09:11

标签: c++ templates

我有一个模板类,它有自己的存储空间,但也可用于查看' (或甚至修改)使用指向数组中某个位置的指针的更大数组。使用例如查看更大的阵列来完成(见下面的完整示例):

/

当数组标记为Tensor<double> t; t.view(&array[i]); 时,可以使用以下内容

const

我现在的问题是:

我想用Tensor<const double> t; t.view(&array[i]); 的一个模板参数编写一个函数,可以用来映射Tensor<...> - 数组并修改地图的副本。如何从嵌套模板中删除const&#39;?或者,如果无法做到这一点,我如何使用地图而不在模板中标记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>>(...) 了。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

考虑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 { other[0], other[1], other[2], other[3] },
          m_data(m_container)
    { }

  2. Tensor<double>Tensor<double const>是完全不同的类型,因此它们需要可以相互构建:

    Tensor(Tensor<typename std::remove_const<T>::type> const& other);
    Tensor(Tensor <T const> const& other);
    // both with same implementation as above
    我们不需要所有组合,但我们免费获得它们......或者,模板构造函数:
    template<typename TT>
    Tensor(Tensor<TT> const& other);
    这甚至允许您初始化e。 G。来自e的双张量。 G。一个int张量 - 如果需要与否,决定你......