Windows与Linux上的std :: string的可移植性和长度

val*_*tis 0 c++ portability stl stdstring c++11

我遇到了一些C++ 11 std::string长度的可移植性问题.在Windows上它是long long unsigned int在Linux和Mac上long unsigned int.我的理解是使用auto是一种解决这类问题的标准方法,但是我很难找到一种通过类接口公开这些属性的可移植方法.


以下类在Linux GCC 7.3.0(以及MacOS)上编译和运行没有问题:

g++ -g -O2 -std=c++11 -Werror=conversion stringwrap.cc
./a.out
3
Run Code Online (Sandbox Code Playgroud)

但是在Windows(g ++ 8.1.0 MinGW-W64 x86_64-posix-seh-rev0)上,我得到以下编译错误:

C:\temp\v0.11>g++ -g -O2 -std=c++11 -Werror=conversion stringwrap.cc
In file included from stringwrap.cc:1:
stringwrap.h: In function 'long unsigned int determineFirstPosition(std::__cxx11::string)':
stringwrap.h:35:20: error: conversion from 'std::__cxx11::basic_string<char>::size_type' {aka 'long long unsigned int'}
to 'long unsigned int' may change value [-Werror=conversion]
     return s.length();
            ~~~~~~~~^~
stringwrap.cc: In member function 'long unsigned int Stringwrap::length() const':
stringwrap.cc:9:23: error: conversion from 'std::__cxx11::basic_string<char>::size_type' {aka 'long long unsigned int'}
to 'long unsigned int' may change value [-Werror=conversion]
     return str_.length();
            ~~~~~~~~~~~^~
cc1plus.exe: some warnings being treated as errors
Run Code Online (Sandbox Code Playgroud)

stringwrap.h

#include <iostream>
#include <string>

class Stringwrap
{
  private:
    std::string str_;

  public:

    Stringwrap(const std::string& str);

    unsigned long int length() const;

    unsigned long int getFirstPosition() const;
};

inline unsigned long int determineFirstPosition(const std::string s)
{
    for (unsigned long int i = 0; i < s.length(); ++i)
    {
        switch (s.at(i))
        {
            case ' ':
            {
                break;
            }
            default:
            {
                return i;
            }
        }
    }

    return s.length();
}
Run Code Online (Sandbox Code Playgroud)

stringwrap.cc

#include "stringwrap.h"

Stringwrap::Stringwrap(const std::string& str) : str_(str)
{
}

unsigned long int Stringwrap::length() const
{
    return str_.length();
}

unsigned long int Stringwrap::getFirstPosition() const
{
    return determineFirstPosition(str_);
}

int main()
{
    Stringwrap sw = *new Stringwrap("   x   ");
    std::cout << sw.getFirstPosition() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试将所有的unsigned long ints 更改为auto,并且-std=c++11我得到以下错误:

C:\temp\v0.11>g++ -g -O2 -std=c++11 -Werror=conversion stringwrap.cc
In file included from stringwrap.cc:1:
stringwrap.h:13:19: error: 'length' function uses 'auto' type specifier without trailing return type
     auto length() const;
                   ^~~~~
stringwrap.h:13:19: note: deduced return type only available with -std=c++14 or -std=gnu++14
stringwrap.h:15:29: error: 'getFirstPosition' function uses 'auto' type specifier without trailing return type
     auto getFirstPosition() const;
                             ^~~~~
stringwrap.h:15:29: note: deduced return type only available with -std=c++14 or -std=gnu++14
stringwrap.h:18:55: error: 'determineFirstPosition' function uses 'auto' type specifier without trailing return type
 inline auto determineFirstPosition(const std::string s)
                                                       ^
stringwrap.h:18:55: note: deduced return type only available with -std=c++14 or -std=gnu++14
stringwrap.h: In function 'auto determineFirstPosition(std::__cxx11::string)':
stringwrap.h:35:21: error: inconsistent deduction for auto return type: 'int' and then 'long long unsigned int'
     return s.length();
                     ^
stringwrap.cc: At global scope:
stringwrap.cc:7:27: error: 'length' function uses 'auto' type specifier without trailing return type
 auto Stringwrap::length() const
                           ^~~~~
stringwrap.cc:7:27: note: deduced return type only available with -std=c++14 or -std=gnu++14
stringwrap.cc:12:37: error: 'getFirstPosition' function uses 'auto' type specifier without trailing return type
 auto Stringwrap::getFirstPosition() const
                                     ^~~~~
stringwrap.cc:12:37: note: deduced return type only available with -std=c++14 or -std=gnu++14
Run Code Online (Sandbox Code Playgroud)

当我使用auto和编译时--std=c++14,我收到以下错误:

C:\temp\v0.11>g++ -g -O2 -std=c++14 -Werror=conversion stringwrap.cc
In file included from stringwrap.cc:1:
stringwrap.h: In function 'auto determineFirstPosition(std::__cxx11::string)':
stringwrap.h:35:21: error: inconsistent deduction for auto return type: 'int' and then 'long long unsigned int'
     return s.length();
                     ^
Run Code Online (Sandbox Code Playgroud)

问题:如何编写可避免STL数据类型中的类型转换的可移植C++ 11代码(Linux,Windows)std::string(如上所示)?

Use*_*ess 5

查看std::string文档,您可以看到调用的类型

std::string::size_type
Run Code Online (Sandbox Code Playgroud)

所以就这样吧.您不需要知道或猜测它是typedef 原始类型- 您已经有一个可用的名称,保证是正确的.