How do write template function that can get a substring of a QString or a std::string?
I'd like to write a template function that can handle both QString
and std::string
in order to reduce copied code. Unfortunately, QString
does not implement the substr
member function. QString::mid(int, int)
seems to be the Qt analogue. What is the best way to handle this discrepancy? Below is the function I have that should act on std::string-like objects:
Template function:
template <typename StringType>
void do_something(StringType s, StringType::size_type start, StringType::size_type length) {
// Not defined if StringType == QString
StringType sub_s = s.substr(start, length);
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
My guess is that I will need to create another function get_substr
that is defined for both std::string
and QString
, which I can call in do_something
, but I am not sure if this is the ideal solution.
c++ qt templates stdstring qstring
add a comment |
I'd like to write a template function that can handle both QString
and std::string
in order to reduce copied code. Unfortunately, QString
does not implement the substr
member function. QString::mid(int, int)
seems to be the Qt analogue. What is the best way to handle this discrepancy? Below is the function I have that should act on std::string-like objects:
Template function:
template <typename StringType>
void do_something(StringType s, StringType::size_type start, StringType::size_type length) {
// Not defined if StringType == QString
StringType sub_s = s.substr(start, length);
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
My guess is that I will need to create another function get_substr
that is defined for both std::string
and QString
, which I can call in do_something
, but I am not sure if this is the ideal solution.
c++ qt templates stdstring qstring
5
Traits/Policy or simple overload seems fine to handle the difference part.
– Jarod42
Dec 31 '18 at 23:22
1
QString
hasbegin()
andend()
members, so any range algorithm should work equally.
– zett42
Dec 31 '18 at 23:48
user zett42 has given an excellent and valid solution, however my answer provides an alternative approach that usesQString
'stoStdString()
member function. Thought I'd just provide you with another working solution as it would increase your available toolset.
– Francis Cugler
Jan 2 at 1:14
add a comment |
I'd like to write a template function that can handle both QString
and std::string
in order to reduce copied code. Unfortunately, QString
does not implement the substr
member function. QString::mid(int, int)
seems to be the Qt analogue. What is the best way to handle this discrepancy? Below is the function I have that should act on std::string-like objects:
Template function:
template <typename StringType>
void do_something(StringType s, StringType::size_type start, StringType::size_type length) {
// Not defined if StringType == QString
StringType sub_s = s.substr(start, length);
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
My guess is that I will need to create another function get_substr
that is defined for both std::string
and QString
, which I can call in do_something
, but I am not sure if this is the ideal solution.
c++ qt templates stdstring qstring
I'd like to write a template function that can handle both QString
and std::string
in order to reduce copied code. Unfortunately, QString
does not implement the substr
member function. QString::mid(int, int)
seems to be the Qt analogue. What is the best way to handle this discrepancy? Below is the function I have that should act on std::string-like objects:
Template function:
template <typename StringType>
void do_something(StringType s, StringType::size_type start, StringType::size_type length) {
// Not defined if StringType == QString
StringType sub_s = s.substr(start, length);
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
My guess is that I will need to create another function get_substr
that is defined for both std::string
and QString
, which I can call in do_something
, but I am not sure if this is the ideal solution.
c++ qt templates stdstring qstring
c++ qt templates stdstring qstring
edited Dec 31 '18 at 23:20
Flimzy
38.7k106597
38.7k106597
asked Dec 31 '18 at 23:19
Ben JonesBen Jones
608517
608517
5
Traits/Policy or simple overload seems fine to handle the difference part.
– Jarod42
Dec 31 '18 at 23:22
1
QString
hasbegin()
andend()
members, so any range algorithm should work equally.
– zett42
Dec 31 '18 at 23:48
user zett42 has given an excellent and valid solution, however my answer provides an alternative approach that usesQString
'stoStdString()
member function. Thought I'd just provide you with another working solution as it would increase your available toolset.
– Francis Cugler
Jan 2 at 1:14
add a comment |
5
Traits/Policy or simple overload seems fine to handle the difference part.
– Jarod42
Dec 31 '18 at 23:22
1
QString
hasbegin()
andend()
members, so any range algorithm should work equally.
– zett42
Dec 31 '18 at 23:48
user zett42 has given an excellent and valid solution, however my answer provides an alternative approach that usesQString
'stoStdString()
member function. Thought I'd just provide you with another working solution as it would increase your available toolset.
– Francis Cugler
Jan 2 at 1:14
5
5
Traits/Policy or simple overload seems fine to handle the difference part.
– Jarod42
Dec 31 '18 at 23:22
Traits/Policy or simple overload seems fine to handle the difference part.
– Jarod42
Dec 31 '18 at 23:22
1
1
QString
has begin()
and end()
members, so any range algorithm should work equally.– zett42
Dec 31 '18 at 23:48
QString
has begin()
and end()
members, so any range algorithm should work equally.– zett42
Dec 31 '18 at 23:48
user zett42 has given an excellent and valid solution, however my answer provides an alternative approach that uses
QString
's toStdString()
member function. Thought I'd just provide you with another working solution as it would increase your available toolset.– Francis Cugler
Jan 2 at 1:14
user zett42 has given an excellent and valid solution, however my answer provides an alternative approach that uses
QString
's toStdString()
member function. Thought I'd just provide you with another working solution as it would increase your available toolset.– Francis Cugler
Jan 2 at 1:14
add a comment |
2 Answers
2
active
oldest
votes
Both std::string
and QString
have data()
and size()
members, so you could construct a std::basic_string_view
for unified string operations:
#include <iostream>
#include <string_view>
template <typename StringType>
void do_something( StringType const& s, typename StringType::size_type start, typename StringType::size_type length )
{
std::basic_string_view sv( s.data(), s.size() );
auto sub_s = sv.substr( start, length );
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
Live Demo
QString::data() /*const*/
returns/*const*/QChar*
. Which is incompatible withstd::basic_string_view
– Jarod42
Jan 2 at 19:09
add a comment |
As of the time of writing this completed answer, user zett42
has given a valid solution to your problem. It took me some time to properly install Qt
and to integrate it into Visual Studio 2017, since now that I have it working I am now finally able to properly build and compile my code to make sure that it works without any issues or bugs.
I think the simplest thing to do would be to use QString
's toStdString()
function. You can write all of your functionality with the default std::string
version, and then just specialize the QString
overloaded version that just calls the std::string
version by converting the contents of the QString
to a std::string
. I will use a simple printString()
function to demonstrate this in the simplest manner; you can take this approach and expand it from here.
#include <string>
#include <iostream>
#include <QString>
// defaulted std::string version (full implementation of function)
template <typename StringType>
void printString(const StringType& s) {
std::cout << s << 'n';
}
// specialized overloaded QString version (it calls the std::string version)
template<>
void printString<QString>(const QString& s ) {
printString(s.toStdString());
}
int main() {
const std::string str( "I am an original std::string" );
const QString qStr( "I am a QString converted to a std::string" );
printString(str);
printString(qStr);
return 0;
}
-Output-
I am an original std::string
I am a QString converted to a std::string
I think this is the easiest way to achieve what you are asking for. This also has the advantage that if you have to make a modification to your implementation you only have to change the std::string
version.
You might use overload instead of specialization.
– Jarod42
Jan 2 at 19:03
You create (unnecessary) copy
– Jarod42
Jan 2 at 19:05
That can easily be fixed with move semantics: I can update the answer to reflect it.
– Francis Cugler
Jan 2 at 23:47
For your changes, better to use const reference for printString, and remove all std::move. Edited to reflect my last remarks.
– Jarod42
Jan 3 at 8:49
I primary meant the "conversion" fromQString
tostring
does allocation which is not always wanted/accepted. Might be fine in some cases but if strings are huge, it might be really problematic.
– Jarod42
Jan 3 at 8:54
|
show 1 more 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%2f53992090%2fhow-do-write-template-function-that-can-get-a-substring-of-a-qstring-or-a-stds%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Both std::string
and QString
have data()
and size()
members, so you could construct a std::basic_string_view
for unified string operations:
#include <iostream>
#include <string_view>
template <typename StringType>
void do_something( StringType const& s, typename StringType::size_type start, typename StringType::size_type length )
{
std::basic_string_view sv( s.data(), s.size() );
auto sub_s = sv.substr( start, length );
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
Live Demo
QString::data() /*const*/
returns/*const*/QChar*
. Which is incompatible withstd::basic_string_view
– Jarod42
Jan 2 at 19:09
add a comment |
Both std::string
and QString
have data()
and size()
members, so you could construct a std::basic_string_view
for unified string operations:
#include <iostream>
#include <string_view>
template <typename StringType>
void do_something( StringType const& s, typename StringType::size_type start, typename StringType::size_type length )
{
std::basic_string_view sv( s.data(), s.size() );
auto sub_s = sv.substr( start, length );
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
Live Demo
QString::data() /*const*/
returns/*const*/QChar*
. Which is incompatible withstd::basic_string_view
– Jarod42
Jan 2 at 19:09
add a comment |
Both std::string
and QString
have data()
and size()
members, so you could construct a std::basic_string_view
for unified string operations:
#include <iostream>
#include <string_view>
template <typename StringType>
void do_something( StringType const& s, typename StringType::size_type start, typename StringType::size_type length )
{
std::basic_string_view sv( s.data(), s.size() );
auto sub_s = sv.substr( start, length );
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
Live Demo
Both std::string
and QString
have data()
and size()
members, so you could construct a std::basic_string_view
for unified string operations:
#include <iostream>
#include <string_view>
template <typename StringType>
void do_something( StringType const& s, typename StringType::size_type start, typename StringType::size_type length )
{
std::basic_string_view sv( s.data(), s.size() );
auto sub_s = sv.substr( start, length );
// Do something with the substring, for instance:
std::cout << "Length of substring is " << sub_s.length() << std::endl;
}
Live Demo
answered Jan 1 at 2:30
zett42zett42
7,3633740
7,3633740
QString::data() /*const*/
returns/*const*/QChar*
. Which is incompatible withstd::basic_string_view
– Jarod42
Jan 2 at 19:09
add a comment |
QString::data() /*const*/
returns/*const*/QChar*
. Which is incompatible withstd::basic_string_view
– Jarod42
Jan 2 at 19:09
QString::data() /*const*/
returns /*const*/QChar*
. Which is incompatible with std::basic_string_view
– Jarod42
Jan 2 at 19:09
QString::data() /*const*/
returns /*const*/QChar*
. Which is incompatible with std::basic_string_view
– Jarod42
Jan 2 at 19:09
add a comment |
As of the time of writing this completed answer, user zett42
has given a valid solution to your problem. It took me some time to properly install Qt
and to integrate it into Visual Studio 2017, since now that I have it working I am now finally able to properly build and compile my code to make sure that it works without any issues or bugs.
I think the simplest thing to do would be to use QString
's toStdString()
function. You can write all of your functionality with the default std::string
version, and then just specialize the QString
overloaded version that just calls the std::string
version by converting the contents of the QString
to a std::string
. I will use a simple printString()
function to demonstrate this in the simplest manner; you can take this approach and expand it from here.
#include <string>
#include <iostream>
#include <QString>
// defaulted std::string version (full implementation of function)
template <typename StringType>
void printString(const StringType& s) {
std::cout << s << 'n';
}
// specialized overloaded QString version (it calls the std::string version)
template<>
void printString<QString>(const QString& s ) {
printString(s.toStdString());
}
int main() {
const std::string str( "I am an original std::string" );
const QString qStr( "I am a QString converted to a std::string" );
printString(str);
printString(qStr);
return 0;
}
-Output-
I am an original std::string
I am a QString converted to a std::string
I think this is the easiest way to achieve what you are asking for. This also has the advantage that if you have to make a modification to your implementation you only have to change the std::string
version.
You might use overload instead of specialization.
– Jarod42
Jan 2 at 19:03
You create (unnecessary) copy
– Jarod42
Jan 2 at 19:05
That can easily be fixed with move semantics: I can update the answer to reflect it.
– Francis Cugler
Jan 2 at 23:47
For your changes, better to use const reference for printString, and remove all std::move. Edited to reflect my last remarks.
– Jarod42
Jan 3 at 8:49
I primary meant the "conversion" fromQString
tostring
does allocation which is not always wanted/accepted. Might be fine in some cases but if strings are huge, it might be really problematic.
– Jarod42
Jan 3 at 8:54
|
show 1 more comment
As of the time of writing this completed answer, user zett42
has given a valid solution to your problem. It took me some time to properly install Qt
and to integrate it into Visual Studio 2017, since now that I have it working I am now finally able to properly build and compile my code to make sure that it works without any issues or bugs.
I think the simplest thing to do would be to use QString
's toStdString()
function. You can write all of your functionality with the default std::string
version, and then just specialize the QString
overloaded version that just calls the std::string
version by converting the contents of the QString
to a std::string
. I will use a simple printString()
function to demonstrate this in the simplest manner; you can take this approach and expand it from here.
#include <string>
#include <iostream>
#include <QString>
// defaulted std::string version (full implementation of function)
template <typename StringType>
void printString(const StringType& s) {
std::cout << s << 'n';
}
// specialized overloaded QString version (it calls the std::string version)
template<>
void printString<QString>(const QString& s ) {
printString(s.toStdString());
}
int main() {
const std::string str( "I am an original std::string" );
const QString qStr( "I am a QString converted to a std::string" );
printString(str);
printString(qStr);
return 0;
}
-Output-
I am an original std::string
I am a QString converted to a std::string
I think this is the easiest way to achieve what you are asking for. This also has the advantage that if you have to make a modification to your implementation you only have to change the std::string
version.
You might use overload instead of specialization.
– Jarod42
Jan 2 at 19:03
You create (unnecessary) copy
– Jarod42
Jan 2 at 19:05
That can easily be fixed with move semantics: I can update the answer to reflect it.
– Francis Cugler
Jan 2 at 23:47
For your changes, better to use const reference for printString, and remove all std::move. Edited to reflect my last remarks.
– Jarod42
Jan 3 at 8:49
I primary meant the "conversion" fromQString
tostring
does allocation which is not always wanted/accepted. Might be fine in some cases but if strings are huge, it might be really problematic.
– Jarod42
Jan 3 at 8:54
|
show 1 more comment
As of the time of writing this completed answer, user zett42
has given a valid solution to your problem. It took me some time to properly install Qt
and to integrate it into Visual Studio 2017, since now that I have it working I am now finally able to properly build and compile my code to make sure that it works without any issues or bugs.
I think the simplest thing to do would be to use QString
's toStdString()
function. You can write all of your functionality with the default std::string
version, and then just specialize the QString
overloaded version that just calls the std::string
version by converting the contents of the QString
to a std::string
. I will use a simple printString()
function to demonstrate this in the simplest manner; you can take this approach and expand it from here.
#include <string>
#include <iostream>
#include <QString>
// defaulted std::string version (full implementation of function)
template <typename StringType>
void printString(const StringType& s) {
std::cout << s << 'n';
}
// specialized overloaded QString version (it calls the std::string version)
template<>
void printString<QString>(const QString& s ) {
printString(s.toStdString());
}
int main() {
const std::string str( "I am an original std::string" );
const QString qStr( "I am a QString converted to a std::string" );
printString(str);
printString(qStr);
return 0;
}
-Output-
I am an original std::string
I am a QString converted to a std::string
I think this is the easiest way to achieve what you are asking for. This also has the advantage that if you have to make a modification to your implementation you only have to change the std::string
version.
As of the time of writing this completed answer, user zett42
has given a valid solution to your problem. It took me some time to properly install Qt
and to integrate it into Visual Studio 2017, since now that I have it working I am now finally able to properly build and compile my code to make sure that it works without any issues or bugs.
I think the simplest thing to do would be to use QString
's toStdString()
function. You can write all of your functionality with the default std::string
version, and then just specialize the QString
overloaded version that just calls the std::string
version by converting the contents of the QString
to a std::string
. I will use a simple printString()
function to demonstrate this in the simplest manner; you can take this approach and expand it from here.
#include <string>
#include <iostream>
#include <QString>
// defaulted std::string version (full implementation of function)
template <typename StringType>
void printString(const StringType& s) {
std::cout << s << 'n';
}
// specialized overloaded QString version (it calls the std::string version)
template<>
void printString<QString>(const QString& s ) {
printString(s.toStdString());
}
int main() {
const std::string str( "I am an original std::string" );
const QString qStr( "I am a QString converted to a std::string" );
printString(str);
printString(qStr);
return 0;
}
-Output-
I am an original std::string
I am a QString converted to a std::string
I think this is the easiest way to achieve what you are asking for. This also has the advantage that if you have to make a modification to your implementation you only have to change the std::string
version.
edited Jan 3 at 8:46
Jarod42
117k12103185
117k12103185
answered Jan 2 at 1:01
Francis CuglerFrancis Cugler
4,67411227
4,67411227
You might use overload instead of specialization.
– Jarod42
Jan 2 at 19:03
You create (unnecessary) copy
– Jarod42
Jan 2 at 19:05
That can easily be fixed with move semantics: I can update the answer to reflect it.
– Francis Cugler
Jan 2 at 23:47
For your changes, better to use const reference for printString, and remove all std::move. Edited to reflect my last remarks.
– Jarod42
Jan 3 at 8:49
I primary meant the "conversion" fromQString
tostring
does allocation which is not always wanted/accepted. Might be fine in some cases but if strings are huge, it might be really problematic.
– Jarod42
Jan 3 at 8:54
|
show 1 more comment
You might use overload instead of specialization.
– Jarod42
Jan 2 at 19:03
You create (unnecessary) copy
– Jarod42
Jan 2 at 19:05
That can easily be fixed with move semantics: I can update the answer to reflect it.
– Francis Cugler
Jan 2 at 23:47
For your changes, better to use const reference for printString, and remove all std::move. Edited to reflect my last remarks.
– Jarod42
Jan 3 at 8:49
I primary meant the "conversion" fromQString
tostring
does allocation which is not always wanted/accepted. Might be fine in some cases but if strings are huge, it might be really problematic.
– Jarod42
Jan 3 at 8:54
You might use overload instead of specialization.
– Jarod42
Jan 2 at 19:03
You might use overload instead of specialization.
– Jarod42
Jan 2 at 19:03
You create (unnecessary) copy
– Jarod42
Jan 2 at 19:05
You create (unnecessary) copy
– Jarod42
Jan 2 at 19:05
That can easily be fixed with move semantics: I can update the answer to reflect it.
– Francis Cugler
Jan 2 at 23:47
That can easily be fixed with move semantics: I can update the answer to reflect it.
– Francis Cugler
Jan 2 at 23:47
For your changes, better to use const reference for printString, and remove all std::move. Edited to reflect my last remarks.
– Jarod42
Jan 3 at 8:49
For your changes, better to use const reference for printString, and remove all std::move. Edited to reflect my last remarks.
– Jarod42
Jan 3 at 8:49
I primary meant the "conversion" from
QString
to string
does allocation which is not always wanted/accepted. Might be fine in some cases but if strings are huge, it might be really problematic.– Jarod42
Jan 3 at 8:54
I primary meant the "conversion" from
QString
to string
does allocation which is not always wanted/accepted. Might be fine in some cases but if strings are huge, it might be really problematic.– Jarod42
Jan 3 at 8:54
|
show 1 more 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.
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%2f53992090%2fhow-do-write-template-function-that-can-get-a-substring-of-a-qstring-or-a-stds%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
5
Traits/Policy or simple overload seems fine to handle the difference part.
– Jarod42
Dec 31 '18 at 23:22
1
QString
hasbegin()
andend()
members, so any range algorithm should work equally.– zett42
Dec 31 '18 at 23:48
user zett42 has given an excellent and valid solution, however my answer provides an alternative approach that uses
QString
'stoStdString()
member function. Thought I'd just provide you with another working solution as it would increase your available toolset.– Francis Cugler
Jan 2 at 1:14