我有一个将“ 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 使用 decltype
和 declval
建议的 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::declval
与 decltype
一起:
template <typename Cont>
class ContainerHolder {
using Pointer = decltype(&std::declval<Cont&>()[0]);
...
};
关于C++:根据模板参数设置指针的常量性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33673213/