Portability and length of std::string on Windows vs. Linux











up vote
0
down vote

favorite












I'm running into some portability problems with C++11 std::string length. On Windows it is long long unsigned int but on Linux and Mac it is long unsigned int. My understanding is that using auto is a standard approach to resolving problems like this, but I'm having some difficulty finding a portable way to expose these attributes via a class interface.





The following class compiles and runs without problems on Linux GCC 7.3.0 (and also on MacOS):



g++ -g -O2 -std=c++11 -Werror=conversion stringwrap.cc
./a.out
3




But on Windows (g++ 8.1.0 MinGW-W64 x86_64-posix-seh-rev0), I get the following compile error:



C:tempv0.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




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();
}




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;
}




I've tried changing all of the unsigned long ints to auto, and with -std=c++11 I get the following errors:



C:tempv0.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




When I use auto and compile --std=c++14, I get the following error:



C:tempv0.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();
^




Question: How can I write portable C++11 code (Linux, Windows) that avoids type conversions in STL data types like std::string (as demonstrated above)?










share|improve this question




















  • 3




    C++11 doesn't support return type deduction, you need to use trailing return type auto foo() -> std::string::size_type {...}
    – felix
    Nov 20 at 14:57












  • just use size_t. Described problem is result of using 32 o 64 bit build type (system) .
    – Marek R
    Nov 20 at 15:00






  • 3




    @MarekR That isn't portable. There is no requirement that std::string::size_type is size_t.
    – NathanOliver
    Nov 20 at 15:00










  • @NathanOliver it is, in a sense. Since std::string size_type isstd::allocator_traits<Allocator>::size_type, and for standard allocator size_type would be make_unsigned_t<difference_type>, and the latter is ptrdiff_t, and that becomes size_t for all intents and purposes.
    – SergeyA
    Nov 20 at 15:12










  • @NathanOliver There is no requirement Perhaps, but size_t should be no smaller than container size types, and is therefore safe to use.
    – n.m.
    Nov 20 at 15:26















up vote
0
down vote

favorite












I'm running into some portability problems with C++11 std::string length. On Windows it is long long unsigned int but on Linux and Mac it is long unsigned int. My understanding is that using auto is a standard approach to resolving problems like this, but I'm having some difficulty finding a portable way to expose these attributes via a class interface.





The following class compiles and runs without problems on Linux GCC 7.3.0 (and also on MacOS):



g++ -g -O2 -std=c++11 -Werror=conversion stringwrap.cc
./a.out
3




But on Windows (g++ 8.1.0 MinGW-W64 x86_64-posix-seh-rev0), I get the following compile error:



C:tempv0.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




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();
}




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;
}




I've tried changing all of the unsigned long ints to auto, and with -std=c++11 I get the following errors:



C:tempv0.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




When I use auto and compile --std=c++14, I get the following error:



C:tempv0.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();
^




Question: How can I write portable C++11 code (Linux, Windows) that avoids type conversions in STL data types like std::string (as demonstrated above)?










share|improve this question




















  • 3




    C++11 doesn't support return type deduction, you need to use trailing return type auto foo() -> std::string::size_type {...}
    – felix
    Nov 20 at 14:57












  • just use size_t. Described problem is result of using 32 o 64 bit build type (system) .
    – Marek R
    Nov 20 at 15:00






  • 3




    @MarekR That isn't portable. There is no requirement that std::string::size_type is size_t.
    – NathanOliver
    Nov 20 at 15:00










  • @NathanOliver it is, in a sense. Since std::string size_type isstd::allocator_traits<Allocator>::size_type, and for standard allocator size_type would be make_unsigned_t<difference_type>, and the latter is ptrdiff_t, and that becomes size_t for all intents and purposes.
    – SergeyA
    Nov 20 at 15:12










  • @NathanOliver There is no requirement Perhaps, but size_t should be no smaller than container size types, and is therefore safe to use.
    – n.m.
    Nov 20 at 15:26













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm running into some portability problems with C++11 std::string length. On Windows it is long long unsigned int but on Linux and Mac it is long unsigned int. My understanding is that using auto is a standard approach to resolving problems like this, but I'm having some difficulty finding a portable way to expose these attributes via a class interface.





The following class compiles and runs without problems on Linux GCC 7.3.0 (and also on MacOS):



g++ -g -O2 -std=c++11 -Werror=conversion stringwrap.cc
./a.out
3




But on Windows (g++ 8.1.0 MinGW-W64 x86_64-posix-seh-rev0), I get the following compile error:



C:tempv0.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




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();
}




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;
}




I've tried changing all of the unsigned long ints to auto, and with -std=c++11 I get the following errors:



C:tempv0.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




When I use auto and compile --std=c++14, I get the following error:



C:tempv0.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();
^




Question: How can I write portable C++11 code (Linux, Windows) that avoids type conversions in STL data types like std::string (as demonstrated above)?










share|improve this question















I'm running into some portability problems with C++11 std::string length. On Windows it is long long unsigned int but on Linux and Mac it is long unsigned int. My understanding is that using auto is a standard approach to resolving problems like this, but I'm having some difficulty finding a portable way to expose these attributes via a class interface.





The following class compiles and runs without problems on Linux GCC 7.3.0 (and also on MacOS):



g++ -g -O2 -std=c++11 -Werror=conversion stringwrap.cc
./a.out
3




But on Windows (g++ 8.1.0 MinGW-W64 x86_64-posix-seh-rev0), I get the following compile error:



C:tempv0.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




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();
}




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;
}




I've tried changing all of the unsigned long ints to auto, and with -std=c++11 I get the following errors:



C:tempv0.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




When I use auto and compile --std=c++14, I get the following error:



C:tempv0.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();
^




Question: How can I write portable C++11 code (Linux, Windows) that avoids type conversions in STL data types like std::string (as demonstrated above)?







c++ c++11 stl portability stdstring






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 at 17:44

























asked Nov 20 at 14:54









vallismortis

3,372103963




3,372103963








  • 3




    C++11 doesn't support return type deduction, you need to use trailing return type auto foo() -> std::string::size_type {...}
    – felix
    Nov 20 at 14:57












  • just use size_t. Described problem is result of using 32 o 64 bit build type (system) .
    – Marek R
    Nov 20 at 15:00






  • 3




    @MarekR That isn't portable. There is no requirement that std::string::size_type is size_t.
    – NathanOliver
    Nov 20 at 15:00










  • @NathanOliver it is, in a sense. Since std::string size_type isstd::allocator_traits<Allocator>::size_type, and for standard allocator size_type would be make_unsigned_t<difference_type>, and the latter is ptrdiff_t, and that becomes size_t for all intents and purposes.
    – SergeyA
    Nov 20 at 15:12










  • @NathanOliver There is no requirement Perhaps, but size_t should be no smaller than container size types, and is therefore safe to use.
    – n.m.
    Nov 20 at 15:26














  • 3




    C++11 doesn't support return type deduction, you need to use trailing return type auto foo() -> std::string::size_type {...}
    – felix
    Nov 20 at 14:57












  • just use size_t. Described problem is result of using 32 o 64 bit build type (system) .
    – Marek R
    Nov 20 at 15:00






  • 3




    @MarekR That isn't portable. There is no requirement that std::string::size_type is size_t.
    – NathanOliver
    Nov 20 at 15:00










  • @NathanOliver it is, in a sense. Since std::string size_type isstd::allocator_traits<Allocator>::size_type, and for standard allocator size_type would be make_unsigned_t<difference_type>, and the latter is ptrdiff_t, and that becomes size_t for all intents and purposes.
    – SergeyA
    Nov 20 at 15:12










  • @NathanOliver There is no requirement Perhaps, but size_t should be no smaller than container size types, and is therefore safe to use.
    – n.m.
    Nov 20 at 15:26








3




3




C++11 doesn't support return type deduction, you need to use trailing return type auto foo() -> std::string::size_type {...}
– felix
Nov 20 at 14:57






C++11 doesn't support return type deduction, you need to use trailing return type auto foo() -> std::string::size_type {...}
– felix
Nov 20 at 14:57














just use size_t. Described problem is result of using 32 o 64 bit build type (system) .
– Marek R
Nov 20 at 15:00




just use size_t. Described problem is result of using 32 o 64 bit build type (system) .
– Marek R
Nov 20 at 15:00




3




3




@MarekR That isn't portable. There is no requirement that std::string::size_type is size_t.
– NathanOliver
Nov 20 at 15:00




@MarekR That isn't portable. There is no requirement that std::string::size_type is size_t.
– NathanOliver
Nov 20 at 15:00












@NathanOliver it is, in a sense. Since std::string size_type isstd::allocator_traits<Allocator>::size_type, and for standard allocator size_type would be make_unsigned_t<difference_type>, and the latter is ptrdiff_t, and that becomes size_t for all intents and purposes.
– SergeyA
Nov 20 at 15:12




@NathanOliver it is, in a sense. Since std::string size_type isstd::allocator_traits<Allocator>::size_type, and for standard allocator size_type would be make_unsigned_t<difference_type>, and the latter is ptrdiff_t, and that becomes size_t for all intents and purposes.
– SergeyA
Nov 20 at 15:12












@NathanOliver There is no requirement Perhaps, but size_t should be no smaller than container size types, and is therefore safe to use.
– n.m.
Nov 20 at 15:26




@NathanOliver There is no requirement Perhaps, but size_t should be no smaller than container size types, and is therefore safe to use.
– n.m.
Nov 20 at 15:26












3 Answers
3






active

oldest

votes

















up vote
4
down vote



accepted










std::string provides public types, like std::string::size_type, that you can use to define your function. You can define your determineFirstPosition function like



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

return s.length();
}


and if you don't want to repeat std::string::size_type all over the place you can add a using declaration to your class to shorten the name like



using pos_type = std::string::size_type;


and then you would just use pos_type.






share|improve this answer




























    up vote
    5
    down vote













    Looking at the std::string documentation, you can see the type is called



    std::string::size_type


    so just use that. You don't need to know or guess what primitive type it is a typedef of - you already have a useable name that is guaranteed to be correct.






    share|improve this answer




























      up vote
      2
      down vote













      c++11 cannot use auto return type deduction.



      For c++14, reading your mind, you ported this:



      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();
      }


      to



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

      return s.length();
      }


      in this case your error was



          for (auto i = 0; i < s.length(); ++i)


      because auto i = 0 is an int, not the type of s.length().



      Do



          for (decltype(s.length()) i = 0; i < s.length(); ++i)


      if you want to avoid naming types here.



      Alternatively, you can use std::string::size_type. Alternatively you can write an utility to let you for(:) over indexes into something;



      template<class T> struct tag_t {using type=T;};

      template<class X> using block_deduction = typename tag_t<X>::type;

      template<class It>
      struct range_t {
      It b, e;
      It begin() const { return b; }
      It end() const { return e; }
      };
      template<class S>
      struct indexer_t {
      S s;
      void operator++(){++s;}
      S operator*() const{ return s; }
      friend bool operator==( indexer_t const& lhs, indexer_t const& rhs ) {
      return lhs.s == rhs.s;
      }
      friend bool operator!=( indexer_t const& lhs, indexer_t const& rhs ) {
      return lhs.s != rhs.s;
      }
      };
      template<class S>
      range_t<indexer_t<S>> indexes( block_deduction<S> start, S finish ) {
      return {{std::move(start)}, {std::move(finish)}};
      }
      template<class C>
      auto indexes_into( C&& c ) {
      return indexes( 0, c.size() );
      }


      all of which lets you do:



      for( auto i : indexs_into(s) )


      instead of



      for (unsigned long int i = 0; i < s.length(); ++i)


      Live example.



      (as a side bonus,



      template<class C>
      auto iterators_into( C& c ) {
      return indexes( c.begin(), c.end() );
      }


      is also useful, allowing you to iterate over all valid iterators into a container without manually writing a for(;;) loop)






      share|improve this answer





















      • This is fascinating. I'm not going to use this (not right now, at least), but I will definitely study this method. There are some language features in here that are new to me.
        – vallismortis
        Nov 20 at 15:37











      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395683%2fportability-and-length-of-stdstring-on-windows-vs-linux%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      4
      down vote



      accepted










      std::string provides public types, like std::string::size_type, that you can use to define your function. You can define your determineFirstPosition function like



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

      return s.length();
      }


      and if you don't want to repeat std::string::size_type all over the place you can add a using declaration to your class to shorten the name like



      using pos_type = std::string::size_type;


      and then you would just use pos_type.






      share|improve this answer

























        up vote
        4
        down vote



        accepted










        std::string provides public types, like std::string::size_type, that you can use to define your function. You can define your determineFirstPosition function like



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

        return s.length();
        }


        and if you don't want to repeat std::string::size_type all over the place you can add a using declaration to your class to shorten the name like



        using pos_type = std::string::size_type;


        and then you would just use pos_type.






        share|improve this answer























          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          std::string provides public types, like std::string::size_type, that you can use to define your function. You can define your determineFirstPosition function like



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

          return s.length();
          }


          and if you don't want to repeat std::string::size_type all over the place you can add a using declaration to your class to shorten the name like



          using pos_type = std::string::size_type;


          and then you would just use pos_type.






          share|improve this answer












          std::string provides public types, like std::string::size_type, that you can use to define your function. You can define your determineFirstPosition function like



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

          return s.length();
          }


          and if you don't want to repeat std::string::size_type all over the place you can add a using declaration to your class to shorten the name like



          using pos_type = std::string::size_type;


          and then you would just use pos_type.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 20 at 14:59









          NathanOliver

          85.8k15118177




          85.8k15118177
























              up vote
              5
              down vote













              Looking at the std::string documentation, you can see the type is called



              std::string::size_type


              so just use that. You don't need to know or guess what primitive type it is a typedef of - you already have a useable name that is guaranteed to be correct.






              share|improve this answer

























                up vote
                5
                down vote













                Looking at the std::string documentation, you can see the type is called



                std::string::size_type


                so just use that. You don't need to know or guess what primitive type it is a typedef of - you already have a useable name that is guaranteed to be correct.






                share|improve this answer























                  up vote
                  5
                  down vote










                  up vote
                  5
                  down vote









                  Looking at the std::string documentation, you can see the type is called



                  std::string::size_type


                  so just use that. You don't need to know or guess what primitive type it is a typedef of - you already have a useable name that is guaranteed to be correct.






                  share|improve this answer












                  Looking at the std::string documentation, you can see the type is called



                  std::string::size_type


                  so just use that. You don't need to know or guess what primitive type it is a typedef of - you already have a useable name that is guaranteed to be correct.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 20 at 14:59









                  Useless

                  43.3k45394




                  43.3k45394






















                      up vote
                      2
                      down vote













                      c++11 cannot use auto return type deduction.



                      For c++14, reading your mind, you ported this:



                      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();
                      }


                      to



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

                      return s.length();
                      }


                      in this case your error was



                          for (auto i = 0; i < s.length(); ++i)


                      because auto i = 0 is an int, not the type of s.length().



                      Do



                          for (decltype(s.length()) i = 0; i < s.length(); ++i)


                      if you want to avoid naming types here.



                      Alternatively, you can use std::string::size_type. Alternatively you can write an utility to let you for(:) over indexes into something;



                      template<class T> struct tag_t {using type=T;};

                      template<class X> using block_deduction = typename tag_t<X>::type;

                      template<class It>
                      struct range_t {
                      It b, e;
                      It begin() const { return b; }
                      It end() const { return e; }
                      };
                      template<class S>
                      struct indexer_t {
                      S s;
                      void operator++(){++s;}
                      S operator*() const{ return s; }
                      friend bool operator==( indexer_t const& lhs, indexer_t const& rhs ) {
                      return lhs.s == rhs.s;
                      }
                      friend bool operator!=( indexer_t const& lhs, indexer_t const& rhs ) {
                      return lhs.s != rhs.s;
                      }
                      };
                      template<class S>
                      range_t<indexer_t<S>> indexes( block_deduction<S> start, S finish ) {
                      return {{std::move(start)}, {std::move(finish)}};
                      }
                      template<class C>
                      auto indexes_into( C&& c ) {
                      return indexes( 0, c.size() );
                      }


                      all of which lets you do:



                      for( auto i : indexs_into(s) )


                      instead of



                      for (unsigned long int i = 0; i < s.length(); ++i)


                      Live example.



                      (as a side bonus,



                      template<class C>
                      auto iterators_into( C& c ) {
                      return indexes( c.begin(), c.end() );
                      }


                      is also useful, allowing you to iterate over all valid iterators into a container without manually writing a for(;;) loop)






                      share|improve this answer





















                      • This is fascinating. I'm not going to use this (not right now, at least), but I will definitely study this method. There are some language features in here that are new to me.
                        – vallismortis
                        Nov 20 at 15:37















                      up vote
                      2
                      down vote













                      c++11 cannot use auto return type deduction.



                      For c++14, reading your mind, you ported this:



                      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();
                      }


                      to



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

                      return s.length();
                      }


                      in this case your error was



                          for (auto i = 0; i < s.length(); ++i)


                      because auto i = 0 is an int, not the type of s.length().



                      Do



                          for (decltype(s.length()) i = 0; i < s.length(); ++i)


                      if you want to avoid naming types here.



                      Alternatively, you can use std::string::size_type. Alternatively you can write an utility to let you for(:) over indexes into something;



                      template<class T> struct tag_t {using type=T;};

                      template<class X> using block_deduction = typename tag_t<X>::type;

                      template<class It>
                      struct range_t {
                      It b, e;
                      It begin() const { return b; }
                      It end() const { return e; }
                      };
                      template<class S>
                      struct indexer_t {
                      S s;
                      void operator++(){++s;}
                      S operator*() const{ return s; }
                      friend bool operator==( indexer_t const& lhs, indexer_t const& rhs ) {
                      return lhs.s == rhs.s;
                      }
                      friend bool operator!=( indexer_t const& lhs, indexer_t const& rhs ) {
                      return lhs.s != rhs.s;
                      }
                      };
                      template<class S>
                      range_t<indexer_t<S>> indexes( block_deduction<S> start, S finish ) {
                      return {{std::move(start)}, {std::move(finish)}};
                      }
                      template<class C>
                      auto indexes_into( C&& c ) {
                      return indexes( 0, c.size() );
                      }


                      all of which lets you do:



                      for( auto i : indexs_into(s) )


                      instead of



                      for (unsigned long int i = 0; i < s.length(); ++i)


                      Live example.



                      (as a side bonus,



                      template<class C>
                      auto iterators_into( C& c ) {
                      return indexes( c.begin(), c.end() );
                      }


                      is also useful, allowing you to iterate over all valid iterators into a container without manually writing a for(;;) loop)






                      share|improve this answer





















                      • This is fascinating. I'm not going to use this (not right now, at least), but I will definitely study this method. There are some language features in here that are new to me.
                        – vallismortis
                        Nov 20 at 15:37













                      up vote
                      2
                      down vote










                      up vote
                      2
                      down vote









                      c++11 cannot use auto return type deduction.



                      For c++14, reading your mind, you ported this:



                      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();
                      }


                      to



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

                      return s.length();
                      }


                      in this case your error was



                          for (auto i = 0; i < s.length(); ++i)


                      because auto i = 0 is an int, not the type of s.length().



                      Do



                          for (decltype(s.length()) i = 0; i < s.length(); ++i)


                      if you want to avoid naming types here.



                      Alternatively, you can use std::string::size_type. Alternatively you can write an utility to let you for(:) over indexes into something;



                      template<class T> struct tag_t {using type=T;};

                      template<class X> using block_deduction = typename tag_t<X>::type;

                      template<class It>
                      struct range_t {
                      It b, e;
                      It begin() const { return b; }
                      It end() const { return e; }
                      };
                      template<class S>
                      struct indexer_t {
                      S s;
                      void operator++(){++s;}
                      S operator*() const{ return s; }
                      friend bool operator==( indexer_t const& lhs, indexer_t const& rhs ) {
                      return lhs.s == rhs.s;
                      }
                      friend bool operator!=( indexer_t const& lhs, indexer_t const& rhs ) {
                      return lhs.s != rhs.s;
                      }
                      };
                      template<class S>
                      range_t<indexer_t<S>> indexes( block_deduction<S> start, S finish ) {
                      return {{std::move(start)}, {std::move(finish)}};
                      }
                      template<class C>
                      auto indexes_into( C&& c ) {
                      return indexes( 0, c.size() );
                      }


                      all of which lets you do:



                      for( auto i : indexs_into(s) )


                      instead of



                      for (unsigned long int i = 0; i < s.length(); ++i)


                      Live example.



                      (as a side bonus,



                      template<class C>
                      auto iterators_into( C& c ) {
                      return indexes( c.begin(), c.end() );
                      }


                      is also useful, allowing you to iterate over all valid iterators into a container without manually writing a for(;;) loop)






                      share|improve this answer












                      c++11 cannot use auto return type deduction.



                      For c++14, reading your mind, you ported this:



                      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();
                      }


                      to



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

                      return s.length();
                      }


                      in this case your error was



                          for (auto i = 0; i < s.length(); ++i)


                      because auto i = 0 is an int, not the type of s.length().



                      Do



                          for (decltype(s.length()) i = 0; i < s.length(); ++i)


                      if you want to avoid naming types here.



                      Alternatively, you can use std::string::size_type. Alternatively you can write an utility to let you for(:) over indexes into something;



                      template<class T> struct tag_t {using type=T;};

                      template<class X> using block_deduction = typename tag_t<X>::type;

                      template<class It>
                      struct range_t {
                      It b, e;
                      It begin() const { return b; }
                      It end() const { return e; }
                      };
                      template<class S>
                      struct indexer_t {
                      S s;
                      void operator++(){++s;}
                      S operator*() const{ return s; }
                      friend bool operator==( indexer_t const& lhs, indexer_t const& rhs ) {
                      return lhs.s == rhs.s;
                      }
                      friend bool operator!=( indexer_t const& lhs, indexer_t const& rhs ) {
                      return lhs.s != rhs.s;
                      }
                      };
                      template<class S>
                      range_t<indexer_t<S>> indexes( block_deduction<S> start, S finish ) {
                      return {{std::move(start)}, {std::move(finish)}};
                      }
                      template<class C>
                      auto indexes_into( C&& c ) {
                      return indexes( 0, c.size() );
                      }


                      all of which lets you do:



                      for( auto i : indexs_into(s) )


                      instead of



                      for (unsigned long int i = 0; i < s.length(); ++i)


                      Live example.



                      (as a side bonus,



                      template<class C>
                      auto iterators_into( C& c ) {
                      return indexes( c.begin(), c.end() );
                      }


                      is also useful, allowing you to iterate over all valid iterators into a container without manually writing a for(;;) loop)







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 20 at 15:10









                      Yakk - Adam Nevraumont

                      181k19188368




                      181k19188368












                      • This is fascinating. I'm not going to use this (not right now, at least), but I will definitely study this method. There are some language features in here that are new to me.
                        – vallismortis
                        Nov 20 at 15:37


















                      • This is fascinating. I'm not going to use this (not right now, at least), but I will definitely study this method. There are some language features in here that are new to me.
                        – vallismortis
                        Nov 20 at 15:37
















                      This is fascinating. I'm not going to use this (not right now, at least), but I will definitely study this method. There are some language features in here that are new to me.
                      – vallismortis
                      Nov 20 at 15:37




                      This is fascinating. I'm not going to use this (not right now, at least), but I will definitely study this method. There are some language features in here that are new to me.
                      – vallismortis
                      Nov 20 at 15:37


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395683%2fportability-and-length-of-stdstring-on-windows-vs-linux%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Wiesbaden

                      Marschland

                      Dieringhausen