在C ++中进行类型转换的简短而优雅的方法?

时间:2018-12-04 19:28:41

标签: c++ types casting type-conversion

说我想将FROM golang:1.10.5 AS build-env ADD https://github.com/golang/dep/releases/download/v0.4.2/dep-linux-amd64 /usr/bin/dep RUN chmod +x /usr/bin/dep RUN mkdir -p $GOPATH/src/github.com/fzr WORKDIR $GOPATH/src/github.com/fzr COPY Gopkg.toml Gopkg.lock ./ # install project dep RUN dep ensure COPY . ./ RUN go build -o /fzr FROM scratch COPY --from=build-env /fzr ./ ENTRYPOINT ["./fzr"] 的大小存储在std::vector中,据我所知,我有以下选择:

int

还有其他选择可以避免上述所有问题?

3 个答案:

答案 0 :(得分:5)

我要挑战这个问题。您不应该想要一个简短而优雅的解决方案。

使用任何语言(包括C ++)进行铸造,基本上相当于程序员宣誓就职:您有时会这样做,因为它既轻松又轻松,但您不应该这样做。这意味着在某种程度上,您的设计被搞砸了。也许您需要将数组的大小传递给旧的API,但是旧的API并未使用size_t。也许您设计了一段代码来使用float,但是在实际实现中,您将它们视为int

无论如何,强制转换被用来修补代码中其他地方所犯的错误。 您不希望有一个简短的解决方案来解决这个问题。您应该选择露骨而又乏味的内容,原因有二:

  • 它向其他程序员发出信号,说明转换不是一个错误:这是故意的和必要的
  • 使您减少这样做的可能性;而是专注于确保您的类型符合您的预期,而不是目标API的预期。

因此,请采用static_castdynamic_castconst_castreinterpret_cast风格的代码。与其尝试寻找简化转换的方法,不如寻找重构代码的方法,以使它们不必要。


如果您准备忽略所有这些内容,请编写如下内容:

template<typename T, typename U>
T as(U && u) {
    return static_cast<T>(u);
}

int size = as<int>(values.size());

bool poly_type::operator==(base_type const& o) {
    if(this == &o)
        return true;
    if(typeid(*this) == typeid(o)) {
        return as<poly_type const&>(o).value == value;
    } else {
        return false;
     }
}

这至少会减少您最终使用的打字量。

答案 1 :(得分:2)

我将按照您的要求回答您的问题。其他答案则说明了为什么不应该这样做。但是,如果您仍然想拥有此功能,请使用以下功能:

#include <assert.h>
#include <limits.h>

inline int toInt(std::size_t value) {
    assert(value<=MAX_INT);
    return static_cast<int>(value);
}

用法:

int size = toInt(vector.size());

toInt断言输入value是否超出范围。随时根据您的需要进行修改。

答案 2 :(得分:0)

首先在int中存储向量大小(可能超过int的最大值)是一个丑陋的操作。这反映在您的编译器警告中,或者您必须编写难看的代码来抑制该警告这一事实。

static_cast的存在会通知其他正在阅读代码的人此处存在潜在的错误,如果向量大小超过INT_MAX,程序可能会以各种方式发生故障。

显然(我希望如此),最好的解决方案是为存储的值auto size = vector.size();使用正确的类型。

如果您确实出于任何原因决定使用int,那么我建议您添加代码以处理向量的开头太大的情况(例如,在throw声明之前添加int ),或添加代码注释,说明为什么这不可能。

没有任何评论,读者无法分辨您的演员表是否仅仅是因为您想关闭编译器并且不关心潜在的错误;或者如果您知道自己在做什么。