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 int
s 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
add a comment |
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 int
s 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
3
C++11 doesn't support return type deduction, you need to use trailing return typeauto foo() -> std::string::size_type {...}
– felix
Nov 20 at 14:57
just usesize_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 thatstd::string::size_type
issize_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 allocatorsize_type
would bemake_unsigned_t<difference_type>
, and the latter isptrdiff_t
, and that becomessize_t
for all intents and purposes.
– SergeyA
Nov 20 at 15:12
@NathanOliver There is no requirement Perhaps, butsize_t
should be no smaller than container size types, and is therefore safe to use.
– n.m.
Nov 20 at 15:26
add a comment |
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 int
s 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
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 int
s 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
c++ c++11 stl portability stdstring
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 typeauto foo() -> std::string::size_type {...}
– felix
Nov 20 at 14:57
just usesize_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 thatstd::string::size_type
issize_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 allocatorsize_type
would bemake_unsigned_t<difference_type>
, and the latter isptrdiff_t
, and that becomessize_t
for all intents and purposes.
– SergeyA
Nov 20 at 15:12
@NathanOliver There is no requirement Perhaps, butsize_t
should be no smaller than container size types, and is therefore safe to use.
– n.m.
Nov 20 at 15:26
add a comment |
3
C++11 doesn't support return type deduction, you need to use trailing return typeauto foo() -> std::string::size_type {...}
– felix
Nov 20 at 14:57
just usesize_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 thatstd::string::size_type
issize_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 allocatorsize_type
would bemake_unsigned_t<difference_type>
, and the latter isptrdiff_t
, and that becomessize_t
for all intents and purposes.
– SergeyA
Nov 20 at 15:12
@NathanOliver There is no requirement Perhaps, butsize_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 is
std::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 is
std::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
add a comment |
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
.
add a comment |
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.
add a comment |
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)
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
.
add a comment |
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
.
add a comment |
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
.
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
.
answered Nov 20 at 14:59
NathanOliver
85.8k15118177
85.8k15118177
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 20 at 14:59
Useless
43.3k45394
43.3k45394
add a comment |
add a comment |
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)
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
add a comment |
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)
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
add a comment |
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)
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)
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
issize_t
.– NathanOliver
Nov 20 at 15:00
@NathanOliver it is, in a sense. Since std::string size_type is
std::allocator_traits<Allocator>::size_type
, and for standard allocatorsize_type
would bemake_unsigned_t<difference_type>
, and the latter isptrdiff_t
, and that becomessize_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