C ++:根据模板参数

时间:2015-11-12 14:01:32

标签: c++ templates pointers c++11

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

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

  • 如果ContainerHolderFirst可行,那就太好了。我希望该类型的常量将传播到指针。为什么不呢?
  • 我更清楚为什么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);
}

2 个答案:

答案 0 :(得分:1)

你对自己造成了不必要的困难。如果您想要You say Traceback (most recent call last): File "C:\Users\Arvid\Documents\Grupdat\Lab3\test.py", line 7, in <module> j=int(input("You say ")) EOFError: EOF when reading a line 类型,只需询问该表达式的类型。使用std::declval&cont[offset]

decltype

答案 1 :(得分:1)

ContainerHolderSecond的唯一问题是您未正确使用它:

ContainerHolderSecond<array<int,2>> const_holder(const_array);
//                    ^-- insert "const" here

对于ContainerHolderFirstarray<T, N>::pointer(array<T, N> const)::pointer的类型相同的原因是没有自动方法来确定应将const资格添加到哪里嵌套类型,没有语言工具来描述它(也就是说,我们没有const - 限定的typedef或类型别名。)