“size_t”作为类型参数,不再复制投射警告

时间:2012-03-20 11:58:20

标签: c++ templates visual-c++-2005 size-t visual-studio

我一直试图摆脱一些旧代码中的警告(必须使用MSVC 2005,目前正在使用32位版本),但一直在努力摆脱size_tunsigned int转化警告。我们有一个实现

的增长数组的Array<T>实现

template<typename I> const T& at(const I i) const {return atImpl(i);}

方法。当被称为

size_t i = 10; myArray.at(i);

我收到conversion from 'size_t' to 'const unsigned int', possible loss of data警告。 工作理论已经 I被理解为unsigned int,这导致编译器在传递时将size_t转换/转换为unsigned int iat(本来不方便但可以接受)。但是,我既没有在最小的工作示例(本文的底部),也没有在更复杂的最小示例中重现此警告。简单地将参数转换为unsigned int会使警告消失,并且足以满足我们的需求(通过合同,数字适合unsigned int

  1. 我对I在这样的调用中unsigned int的理解是正确的(规范说“因此,typedef-name是另一种类型的同义词.typedef-name确实如此 不引入新类型“,typeid(size_t(1)).name()unsigned intsize_t似乎是typedef已经过了。换句话说,应该或不应该是最小的例子发出警告?据我所知,构建配置是一样的。
  2. 由于我们的代码给了我们警告而最小的例子没有,我必须忽略一些东西。尽管付出了很多努力,但我无法弄清楚是什么。想法?
  3. 由于

    最小的例子:

        template<typename T>
        class A
        {
          int t;
        public:
          template<typename I> T& at(const I i) { return t;}  
        };
    
        int main()
        {  
          size_t i = 10;
          A<int> a; 
          a.at(i) = 5; // no warning, why?
          return 0;
        }
    

1 个答案:

答案 0 :(得分:1)

at函数也是模板化的。 C ++将尝试推导出模板类型参数。这是您的代码中发生的事情,因为您没有在调用中指定类型,例如a.at&lt;为size_t&GT;(1);

此代码将生成警告,因为它已将类型推断为unsigned int,然后我们尝试传递size_t

template <typename T>
class A
{
    int t;
    public:
        template<typename I> T& at(const I i)
        { return t;}
};

int main()
{
    unsigned int j = 5;
    size_t i = 10;
    A<int> a;

    a.at(j) = 4; // deduce template type as unsigned int
    a.at(i) = 5; // generate warning
    return 0;
}

编辑:我实际上在VS中尝试了此代码并生成警告。

Edit2:在我尝试过的代码中,size_t和unsigned int都是4个字节。所以我做了一些挖掘。在旧版本的VS中,size_t被定义为typedef __w64 unsigned int size_t'__ w64'现在已被弃用,但用于标记在移动到64位平台时具有不同大小(例如64对32)的类型。 __w64使编译器将size_t视为不同的类型。

作为实验,我输入了我自己的无符号整数myint,并将行size_t i = 10更改为myint i = 10

使用typedef __w64 unsigned int myint生成警告,其中'typedef unsigned int myint`不会生成警告。