C++:与泛型const指针斗争

Cha*_*via 3 c++ templates stl const

我在一些模板化的代码中遇到了一些烦人的问题 - 最终归结为以下观察:由于某种原因,给定一个STL-ish容器类型T,const typename T::pointer实际上似乎并不是一个常量指针类型,即使T::pointer相当于T::value_type*.

以下示例说明了该问题.假设您有一个模板化函数,它接受一个必须满足STL随机访问容器概念要求的Container.

template <class Container>
void example(Container& c)
{
    const typename Container::pointer p1 = &c[0]; // Error if c is const
    const typename Container::value_type* p2 = &c[0]; 
}
Run Code Online (Sandbox Code Playgroud)

然后,如果我们传递这个函数一个const容器......

const std::vector<int> vec(10);
example(vec);
Run Code Online (Sandbox Code Playgroud)

...我们得到一个无效转换const int*int*.但是为什么const typename Container::pointerconst int*这个例子不一样呢?

请注意,如果我const typename Container::pointer改为简单typename Container::const_pointer编译就好了,但据我所知,const_pointer typedef是一个扩展,(我没有在C++标准容器要求(23.5,表65)中看到它),以及所以我不想用它.

那么如何从容器T中获取通用的,const-correct指针类型呢?(我实在看不出如何做到这一点,而不使用boost :: MPL :: if_与type_traits一起检查,如果容器是不变的......但必须有这样做一个更简洁的方式)

编辑:如果重要,我正在使用gcc 4.3.2来编译它.

AnT*_*AnT 17

它不起作用,因为您const不适用于您认为适用的内容.例如,如果你有

typedef int* IntPtr;
Run Code Online (Sandbox Code Playgroud)

然后

const IntPtr p;
Run Code Online (Sandbox Code Playgroud)

不代表

const int* p;
Run Code Online (Sandbox Code Playgroud)

而是代表

int* const p;
Run Code Online (Sandbox Code Playgroud)

Typedef-name不是宏.一旦类型的"指针"被包装到typedef-name中,就再也无法使用它来创建指向const的类型.即绝对没有办法使用上面的IntPtrtypedef-name来生成等效的

const int* p;
Run Code Online (Sandbox Code Playgroud)

你必须明确地使用pointee类型(就像你使用的那样value_type),或者检查你的容器是否定义了一个不同的typedef-name,const已经包含了"inside"(比如const_pointer或类似的东西).

  • 这可能很难记住.我遇到的最好的提示是读R到L."int*const p"是"const指向int的指针",即指针是const但int是可变的."const int*p"是"指向int的指针",即指针是可变的,但int是const. (2认同)