你如何将智能指针向量转换为一个常量向量,该向量包含指向常量的智能指针?

时间:2018-01-26 07:00:21

标签: c++ casting containers smart-pointers

我有一个名为Thing的班级。 我制作了shared_ptr<Thing>>的向量。 现在我想将它传递给函数或类似的东西:const vector<shared_ptr<const Thing>>

下面的代码编译但我更倾向于避免使用reinterpret_cast来保证类型安全,因为我不知道这会如何影响智能指针的行为。

#include <memory>
#include <vector>

using namespace std;

class Thing {};

typedef vector<shared_ptr<Thing>>             VectorOfThings;
typedef const vector<shared_ptr<const Thing>> VectorOfConstThings;

int main() {
    VectorOfThings *things;
    auto           constThings = reinterpret_cast<VectorOfConstThings *> (things);
}

2 个答案:

答案 0 :(得分:4)

这与智能指针无关; C ++标准不允许容器&lt; T&gt;之间的转换。和容器&lt; T const&gt;。之前已经讨论过这个问题: Why is a vector of pointers not castable to a const vector of const pointers?

可能是铸造转向器&lt; T&gt;到容器&lt; const T&gt;是未定义的行为。

答案 1 :(得分:0)

我写了一个宏来处理类型转换。希望这将消除编写所有锅炉板代码所带来的错误。

TypeHelper.h

Annual_interest_rate | Loan_id | Member_id
 0.2850              |  1      | -9832
 0.1482              |  2      |  6982
 0.065               |  3      | -9832
 0.1754              |  4      |  1234
 0.2387              |  5      |  1234

在这个文件中,我使用宏来定义stl向量类

周围的包装器
#ifndef TYPE_HELPER_H
#define TYPE_HELPER_H

#include <memory>

/**
 * Creates a struct that has two typedefs and has several functions for reinterpret casting the regular type as
 * the constant type
 * @param NAME The name of the generated struct
 * @param REGULAR_TYPE The typedef of the non-constant type
 * @param CONSTANT_TYPE The typedef of the constant type
 * @param ... The template parameters used in REGULAR_TYPE and CONSTANT_TYPE.
 * There must be at least one parameter passed in. Even if the typedefs don't actually use them.
 * TODO If the typedefs don't need a template parameter, the user should not have to supply a dummy one.
 * TODO Implement some kind of checking to make sure that constness is the only difference.
 * TODO what happens if the template is specialized for a const of that type?
 */
#define TYPE_HELPER( NAME, REGULAR_TYPE, CONSTANT_TYPE, ... ) \
template< __VA_ARGS__ > \
struct NAME { \
typedef REGULAR_TYPE regular; \
typedef CONSTANT_TYPE constant; \
static inline constant *cast( regular *pointer ) { return reinterpret_cast<constant *> (pointer); } \
static inline constant &cast( regular &reference ) { return *reinterpret_cast<constant *> (&reference); }  \
static inline std::unique_ptr<constant> cast( std::unique_ptr<regular> unique_ptr ) { \
    return std::move( *( reinterpret_cast<std::unique_ptr<constant> *> (&unique_ptr))); \
} \
static inline std::shared_ptr<constant> cast( std::shared_ptr<regular> shared_ptr ) { \
    return std::move( *( reinterpret_cast<std::shared_ptr<constant> *> (&shared_ptr))); \
} \
};


#endif //TYPE_HELPER_H

最后,我在这里使用类型

#ifndef VECTOR_TYPE_H
#define VECTOR_TYPE_H

#include <vector>
#include "TypeHelper.h"

TYPE_HELPER( VectorType,
             std::vector<std::shared_ptr<T>>,
             const std::vector<std::shared_ptr<const T>>,
             typename T );

#endif //VECTOR_TYPE_H