C++:根据模板参数设置指针的常量性

标签 c++ templates pointers c++11

我有一个将“ View ”管理为变量类型数组的结构。这样做的目的是为 ODE 仿真提供一个统一的状态 vector ,同时以有组织的方式处理来自几个其他类的该 vector 的各个部分。如果这触发了您心中的设计模式,请告诉我。

我的问题是第一个实现 ContainerHolderFirst,使用 Cont::pointer 不编译常量数组。 我对 std::conditional 的下一次尝试,混合在 Cont::const_pointer 中仍然不起作用。 只有第三次尝试使用 std::conditional 和修改 Cont::value_type 编译(并且似乎在我的大型项目中工作)。 我的问题如下:

  • 如果 ContainerHolderFirst 能工作就好了。我希望该类型的 const-ness 会传播到指针。为什么不是呢?
  • 我更不明白为什么 ContainerHolderSecond 不起作用。 https://stackoverflow.com/a/1647394/1707931中的解释而是建议这是要走的路,不是吗? 它确实有效。我的错。
  • 第三种方法是否存在我尚未发现的问题?有没有更简单的方法?

完整的 C++11 代码如下:

Update1:修复 ContainerHolderSecond。它确实通过正确的初始化进行编译。还添加了 Barry 使用 decltypedeclval 建议的 ContainerHolderBarry。 这就留下了一个问题,是否有任何方法是首选的?它们会导致性能差异吗?它们都应该编译成同一个对象,不是吗?

#include <iostream>
#include <array>

template <typename Cont>
class ContainerHolderFirst {
    Cont& data_;

    const static size_t offset_ = 1;
    typename Cont::pointer data_view;
 public:
    ContainerHolderFirst(Cont& data) : data_(data), data_view(&data[offset_]) {}
};

template <typename Cont>
class ContainerHolderSecond {
    using Pointer = typename std::conditional<std::is_const<Cont>::value,
          typename Cont::const_pointer,
          typename Cont::pointer>::type;
    Cont& data_;

    const static size_t offset_ = 1;
    Pointer data_view;

 public:
    ContainerHolderSecond(Cont& data) : data_(data), data_view(&data[offset_]) {}
};

template <typename Cont>
class ContainerHolderBarry {
    using Pointer = decltype(&std::declval<Cont&>()[0]);
    Cont& data_;

    const static size_t offset_ = 1;
    Pointer data_view;

 public:
    ContainerHolderBarry(Cont& data) : data_(data), data_view(&data[offset_]) {}
};


int main() {
    using namespace std;
    array<int, 2> my_array;
    ContainerHolderFirst<array<int, 2>> holder(my_array); // works

    const array<int, 2> const_array{5,7};
    // ContainerHolderFirst<const array<int, 2>> const_holder(const_array);
    /* error: invalid conversion from 'const value_type* {aka const int*}' to 'std::array<int, 2ull>::pointer {aka int*}' [-fpermissive] */

    ContainerHolderSecond<array<int,2>> second_holder(my_array); // works!
    ContainerHolderSecond<const array<int,2>> const_holder(const_array); //updated; works as well; awkward

    ContainerHolderThird<array<int,2>> third_holder(my_array); // still works
    ContainerHolderThird<const array<int,2>> third_const_holder(const_array); //finally compiles as well

    ContainerHolderBarry<array<int,2>> barry_holder(my_array);
    ContainerHolderBarry<const array<int,2>> barry_const_holder(const_array);
}

最佳答案

你给自己增加了不必要的困难。如果您想要&cont[offset] 的类型,只需询问那个表达式 的类型。使用 std::declvaldecltype 一起:

template <typename Cont>
class ContainerHolder {
    using Pointer = decltype(&std::declval<Cont&>()[0]);
    ...
};

关于C++:根据模板参数设置指针的常量性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33673213/

相关文章:

c++ - 创建派生类对象的指针数组。 C++。抽象基类

c++ - 为什么 float 变量通过以一种奇怪的方式在点后切割数字来保存值?

c++ - 控制台输入中基于向上箭头的命令历史记录 (C++)

c++ - 函数模板特化(以 int 值为模板)

c++ - vector::erase with pointer 成员

c++ - 系统包括跨发行版不完全一致

templates - 我可以在 Golang 的另一个模板中使用模板变量吗?

c - 如何访问 C 中结构中索引处的元素?

delphi - 将 Delphi 2009/2010 字符串文字转换为 PAnsiChar

c++ - 避免在多个 C++ 模板特化上重复代码