C++11风格中进行类型转换的正确方式是什么?

3

我有一个像这样的类:

class A {
    void init(int a){
    _data.resize(a); //! (1)
    }

    //other parts of the code are not important ...
private:
    std::list<std::vector<double>> _data;
}

在(1)中,我收到了一条具有以下文本的警告:
implicit conversion from int to size_type(aka unsigned long)

我想知道消除警告的正确方法是什么? 也许像这样:
_data.resize(static_cast<decltype(_data)::size_type>(a)

注意:我认为代码应该更改为:

init(size_t a) 

但是让我们假设我们无法改变类的接口。


8
init(size_t a){ - Revolver_Ocelot
@Revolver_Ocelot 我猜这是正确的方法,但让我们假设我们不能更改接口。 - tty6
1
与其执行任何强制转换,似乎更有用的是检查参数是否可表示为容器的大小类型。 - Kerrek SB
如果不使用C++11,我会说一个简单的static_cast<size_t>()就可以完成工作,而在C++11中,使用decltype代替size_t看起来更好。 - KimKulling
3个回答

7

您的示例代码对于类型转换使用是正确的:

  1. 它明确声明了类型转换的意图。
  2. 它将类型转换为正确的类型,并防止未来 _data 类型更改。
  3. 它使用了正确的类型转换方式。

所以如果不能更改接口,就坚持使用它。

在使用输入之前,最好添加输入检查。检查负值并在转换为无符号数之前进行检查是最基本和有用的检查。


1
我很想加上:在强制类型转换之前检查负的 a。 - Emily L.
你可以查看boost中的numeric_cast,它会为你执行范围检查。 - Stefan Atev

4
最正确的方式就是你所说的方法:
_data.resize(static_cast<decltype(_data)::size_type>(a));

然而,最大的问题是有符号(signed)和无符号(unsigned),你说你只能使用int,所以你可以使用以下代码:

_data.resize(static_cast<unsigned int>(a));

2
像这样简单:
_data.resize(std::size_t(a));

就像这样疯狂:

_data.resize(static_cast<std::size_t>(a));

C风格转换也被支持:
_data.resize((std::size_t)a);

3
作为附注,第一个建议(functional cast)和C风格的强制类型转换是写同一件事情的两种方式。 - eerorika
@user2079303,我知道。我的回答意图是展示有多种方法可以完成同一件事情。所以这里给你 :) - ForceBru
我相信知道。但是我怀疑并非所有寻找正确类型转换方法的人都知道。 - eerorika

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接