Shorthand for overloading multiple functions
Assuming I have code such as the one below:
bool isString(char* arg) { return true; }
bool isString(const char* arg) { return true; }
bool isString(std::string arg) { return true; }
// Any other type...
template <typename type> bool isString(type arg) { return false; }
The question is, does C++ allow for any plausible way to shorten the syntax below to something similar to the concept below (syntactic shorthand/ sugar):
// Could be `char*`, `const char*` or `std::string` here.
bool isString([char*, const char*, std::string] arg) { return true; }
// Any other type...
template <typename type> bool isString(type arg) { return false; }
The examples presented here are not necessarily for detecting strings, but rather to explain the problem of multiple lines of code being dedicated to overloaded functions.
Imagine if I had to test for a 100+ data types for if they were valid or not, I would quickly want a shorter way of coding this rather than typing all 100 overloaded functions
Of course, the drawback to this syntactic shorthand is the fact that the data type of arg
can not then be differentiated (unlike with the standard function overloading).
c++ function-overloading
|
show 3 more comments
Assuming I have code such as the one below:
bool isString(char* arg) { return true; }
bool isString(const char* arg) { return true; }
bool isString(std::string arg) { return true; }
// Any other type...
template <typename type> bool isString(type arg) { return false; }
The question is, does C++ allow for any plausible way to shorten the syntax below to something similar to the concept below (syntactic shorthand/ sugar):
// Could be `char*`, `const char*` or `std::string` here.
bool isString([char*, const char*, std::string] arg) { return true; }
// Any other type...
template <typename type> bool isString(type arg) { return false; }
The examples presented here are not necessarily for detecting strings, but rather to explain the problem of multiple lines of code being dedicated to overloaded functions.
Imagine if I had to test for a 100+ data types for if they were valid or not, I would quickly want a shorter way of coding this rather than typing all 100 overloaded functions
Of course, the drawback to this syntactic shorthand is the fact that the data type of arg
can not then be differentiated (unlike with the standard function overloading).
c++ function-overloading
For numeric types, there isstd::is_arithmetic
.
– halfelf
Nov 21 '18 at 6:03
1
If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.
– StoryTeller
Nov 21 '18 at 6:05
1
@JesperJuhl -isNumber(std::vector<std::string>{})
?
– StoryTeller
Nov 21 '18 at 6:06
1
The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.
– Lapys
Nov 21 '18 at 6:11
1
My point is that you don't need a function. You need a variable templatetemplate<class> bool is_string
and you need to pass it the type of the thing you want to check, not the thing itself.
– n.m.
Nov 21 '18 at 10:48
|
show 3 more comments
Assuming I have code such as the one below:
bool isString(char* arg) { return true; }
bool isString(const char* arg) { return true; }
bool isString(std::string arg) { return true; }
// Any other type...
template <typename type> bool isString(type arg) { return false; }
The question is, does C++ allow for any plausible way to shorten the syntax below to something similar to the concept below (syntactic shorthand/ sugar):
// Could be `char*`, `const char*` or `std::string` here.
bool isString([char*, const char*, std::string] arg) { return true; }
// Any other type...
template <typename type> bool isString(type arg) { return false; }
The examples presented here are not necessarily for detecting strings, but rather to explain the problem of multiple lines of code being dedicated to overloaded functions.
Imagine if I had to test for a 100+ data types for if they were valid or not, I would quickly want a shorter way of coding this rather than typing all 100 overloaded functions
Of course, the drawback to this syntactic shorthand is the fact that the data type of arg
can not then be differentiated (unlike with the standard function overloading).
c++ function-overloading
Assuming I have code such as the one below:
bool isString(char* arg) { return true; }
bool isString(const char* arg) { return true; }
bool isString(std::string arg) { return true; }
// Any other type...
template <typename type> bool isString(type arg) { return false; }
The question is, does C++ allow for any plausible way to shorten the syntax below to something similar to the concept below (syntactic shorthand/ sugar):
// Could be `char*`, `const char*` or `std::string` here.
bool isString([char*, const char*, std::string] arg) { return true; }
// Any other type...
template <typename type> bool isString(type arg) { return false; }
The examples presented here are not necessarily for detecting strings, but rather to explain the problem of multiple lines of code being dedicated to overloaded functions.
Imagine if I had to test for a 100+ data types for if they were valid or not, I would quickly want a shorter way of coding this rather than typing all 100 overloaded functions
Of course, the drawback to this syntactic shorthand is the fact that the data type of arg
can not then be differentiated (unlike with the standard function overloading).
c++ function-overloading
c++ function-overloading
edited Nov 21 '18 at 21:21


halfer
14.5k758111
14.5k758111
asked Nov 21 '18 at 5:56


LapysLapys
3961313
3961313
For numeric types, there isstd::is_arithmetic
.
– halfelf
Nov 21 '18 at 6:03
1
If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.
– StoryTeller
Nov 21 '18 at 6:05
1
@JesperJuhl -isNumber(std::vector<std::string>{})
?
– StoryTeller
Nov 21 '18 at 6:06
1
The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.
– Lapys
Nov 21 '18 at 6:11
1
My point is that you don't need a function. You need a variable templatetemplate<class> bool is_string
and you need to pass it the type of the thing you want to check, not the thing itself.
– n.m.
Nov 21 '18 at 10:48
|
show 3 more comments
For numeric types, there isstd::is_arithmetic
.
– halfelf
Nov 21 '18 at 6:03
1
If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.
– StoryTeller
Nov 21 '18 at 6:05
1
@JesperJuhl -isNumber(std::vector<std::string>{})
?
– StoryTeller
Nov 21 '18 at 6:06
1
The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.
– Lapys
Nov 21 '18 at 6:11
1
My point is that you don't need a function. You need a variable templatetemplate<class> bool is_string
and you need to pass it the type of the thing you want to check, not the thing itself.
– n.m.
Nov 21 '18 at 10:48
For numeric types, there is
std::is_arithmetic
.– halfelf
Nov 21 '18 at 6:03
For numeric types, there is
std::is_arithmetic
.– halfelf
Nov 21 '18 at 6:03
1
1
If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.
– StoryTeller
Nov 21 '18 at 6:05
If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.
– StoryTeller
Nov 21 '18 at 6:05
1
1
@JesperJuhl -
isNumber(std::vector<std::string>{})
?– StoryTeller
Nov 21 '18 at 6:06
@JesperJuhl -
isNumber(std::vector<std::string>{})
?– StoryTeller
Nov 21 '18 at 6:06
1
1
The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.
– Lapys
Nov 21 '18 at 6:11
The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.
– Lapys
Nov 21 '18 at 6:11
1
1
My point is that you don't need a function. You need a variable template
template<class> bool is_string
and you need to pass it the type of the thing you want to check, not the thing itself.– n.m.
Nov 21 '18 at 10:48
My point is that you don't need a function. You need a variable template
template<class> bool is_string
and you need to pass it the type of the thing you want to check, not the thing itself.– n.m.
Nov 21 '18 at 10:48
|
show 3 more comments
4 Answers
4
active
oldest
votes
A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.
#include <string>
#include <iostream>
template <class> const bool is_string = false;
template<> const bool is_string<const char*> = true;
template<> const bool is_string<std::string> = true;
int main() {
const char* z;
std::string p;
int q;
std::cout << is_string<decltype(z)> << "n";
std::cout << is_string<decltype(p)> << "n";
std::cout << is_string<decltype(q)> << "n";
}
If a function interface is desired, it's trivial to provide
template<class T>
constexpr bool is_string_f(const T&) {
return is_string<T>;
}
OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.
#include <type_traits>
template<class X, class ... args>
const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
template <class T>
bool is_string = type_is_one_of<T, char*, const char*, std::string>;
Live example on ideone.
add a comment |
Probably the best approach would be to start with defining a trait identifying your types:
template<typename> struct is_string : std::false_type{};
template<> struct is_string<char*> : std::true_type{};
template<> struct is_string<char const*> : std::true_type{};
template<> struct is_string<std::string> : std::true_type{};
Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this
template<typename T> constexpr bool isString(T) { return is_string<T>::value; }
Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:
template<typename S>
auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;
Some pre-defined traits and utilities are already available in the <type_traits>
header.
I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.
– Lapys
Nov 21 '18 at 6:37
1
@Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?
– StoryTeller
Nov 21 '18 at 6:40
Ah, I see. Thanks.
– Lapys
Nov 21 '18 at 6:42
1
@Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functionsconstexpr
may move them into the same direction but making such type traits will probably work better in general.
– Scheff
Nov 21 '18 at 6:47
add a comment |
Might
#include <type_traits>
#include <string>
template<typename T>
bool is_string(T)
{
return std::is_constructible<std::string, T>::value;
}
be enough?
add a comment |
You might directly do:
template <typename T>
constexpr bool isString()
{
return std::is_same<T, const char*>::value
|| std::is_same<T, char*>::value
|| std::is_same<T, std::string>::value;
}
then if you have to set of overloads, you might use SFINAE:
template <typename T>
std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}
template <typename T>
std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}
or if constexpr
(c++17):
template <typename T>
void foo(/**/)
{
if constexpr (isString<T>()) {
/*..*/
} else {
/*..*/
}
}
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%2f53406038%2fshorthand-for-overloading-multiple-functions%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.
#include <string>
#include <iostream>
template <class> const bool is_string = false;
template<> const bool is_string<const char*> = true;
template<> const bool is_string<std::string> = true;
int main() {
const char* z;
std::string p;
int q;
std::cout << is_string<decltype(z)> << "n";
std::cout << is_string<decltype(p)> << "n";
std::cout << is_string<decltype(q)> << "n";
}
If a function interface is desired, it's trivial to provide
template<class T>
constexpr bool is_string_f(const T&) {
return is_string<T>;
}
OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.
#include <type_traits>
template<class X, class ... args>
const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
template <class T>
bool is_string = type_is_one_of<T, char*, const char*, std::string>;
Live example on ideone.
add a comment |
A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.
#include <string>
#include <iostream>
template <class> const bool is_string = false;
template<> const bool is_string<const char*> = true;
template<> const bool is_string<std::string> = true;
int main() {
const char* z;
std::string p;
int q;
std::cout << is_string<decltype(z)> << "n";
std::cout << is_string<decltype(p)> << "n";
std::cout << is_string<decltype(q)> << "n";
}
If a function interface is desired, it's trivial to provide
template<class T>
constexpr bool is_string_f(const T&) {
return is_string<T>;
}
OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.
#include <type_traits>
template<class X, class ... args>
const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
template <class T>
bool is_string = type_is_one_of<T, char*, const char*, std::string>;
Live example on ideone.
add a comment |
A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.
#include <string>
#include <iostream>
template <class> const bool is_string = false;
template<> const bool is_string<const char*> = true;
template<> const bool is_string<std::string> = true;
int main() {
const char* z;
std::string p;
int q;
std::cout << is_string<decltype(z)> << "n";
std::cout << is_string<decltype(p)> << "n";
std::cout << is_string<decltype(q)> << "n";
}
If a function interface is desired, it's trivial to provide
template<class T>
constexpr bool is_string_f(const T&) {
return is_string<T>;
}
OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.
#include <type_traits>
template<class X, class ... args>
const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
template <class T>
bool is_string = type_is_one_of<T, char*, const char*, std::string>;
Live example on ideone.
A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.
#include <string>
#include <iostream>
template <class> const bool is_string = false;
template<> const bool is_string<const char*> = true;
template<> const bool is_string<std::string> = true;
int main() {
const char* z;
std::string p;
int q;
std::cout << is_string<decltype(z)> << "n";
std::cout << is_string<decltype(p)> << "n";
std::cout << is_string<decltype(q)> << "n";
}
If a function interface is desired, it's trivial to provide
template<class T>
constexpr bool is_string_f(const T&) {
return is_string<T>;
}
OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.
#include <type_traits>
template<class X, class ... args>
const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
template <class T>
bool is_string = type_is_one_of<T, char*, const char*, std::string>;
Live example on ideone.
edited Nov 21 '18 at 11:13
answered Nov 21 '18 at 11:06


n.m.n.m.
71.9k882167
71.9k882167
add a comment |
add a comment |
Probably the best approach would be to start with defining a trait identifying your types:
template<typename> struct is_string : std::false_type{};
template<> struct is_string<char*> : std::true_type{};
template<> struct is_string<char const*> : std::true_type{};
template<> struct is_string<std::string> : std::true_type{};
Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this
template<typename T> constexpr bool isString(T) { return is_string<T>::value; }
Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:
template<typename S>
auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;
Some pre-defined traits and utilities are already available in the <type_traits>
header.
I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.
– Lapys
Nov 21 '18 at 6:37
1
@Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?
– StoryTeller
Nov 21 '18 at 6:40
Ah, I see. Thanks.
– Lapys
Nov 21 '18 at 6:42
1
@Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functionsconstexpr
may move them into the same direction but making such type traits will probably work better in general.
– Scheff
Nov 21 '18 at 6:47
add a comment |
Probably the best approach would be to start with defining a trait identifying your types:
template<typename> struct is_string : std::false_type{};
template<> struct is_string<char*> : std::true_type{};
template<> struct is_string<char const*> : std::true_type{};
template<> struct is_string<std::string> : std::true_type{};
Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this
template<typename T> constexpr bool isString(T) { return is_string<T>::value; }
Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:
template<typename S>
auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;
Some pre-defined traits and utilities are already available in the <type_traits>
header.
I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.
– Lapys
Nov 21 '18 at 6:37
1
@Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?
– StoryTeller
Nov 21 '18 at 6:40
Ah, I see. Thanks.
– Lapys
Nov 21 '18 at 6:42
1
@Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functionsconstexpr
may move them into the same direction but making such type traits will probably work better in general.
– Scheff
Nov 21 '18 at 6:47
add a comment |
Probably the best approach would be to start with defining a trait identifying your types:
template<typename> struct is_string : std::false_type{};
template<> struct is_string<char*> : std::true_type{};
template<> struct is_string<char const*> : std::true_type{};
template<> struct is_string<std::string> : std::true_type{};
Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this
template<typename T> constexpr bool isString(T) { return is_string<T>::value; }
Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:
template<typename S>
auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;
Some pre-defined traits and utilities are already available in the <type_traits>
header.
Probably the best approach would be to start with defining a trait identifying your types:
template<typename> struct is_string : std::false_type{};
template<> struct is_string<char*> : std::true_type{};
template<> struct is_string<char const*> : std::true_type{};
template<> struct is_string<std::string> : std::true_type{};
Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this
template<typename T> constexpr bool isString(T) { return is_string<T>::value; }
Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:
template<typename S>
auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;
Some pre-defined traits and utilities are already available in the <type_traits>
header.
answered Nov 21 '18 at 6:24
StoryTellerStoryTeller
97.9k12199267
97.9k12199267
I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.
– Lapys
Nov 21 '18 at 6:37
1
@Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?
– StoryTeller
Nov 21 '18 at 6:40
Ah, I see. Thanks.
– Lapys
Nov 21 '18 at 6:42
1
@Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functionsconstexpr
may move them into the same direction but making such type traits will probably work better in general.
– Scheff
Nov 21 '18 at 6:47
add a comment |
I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.
– Lapys
Nov 21 '18 at 6:37
1
@Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?
– StoryTeller
Nov 21 '18 at 6:40
Ah, I see. Thanks.
– Lapys
Nov 21 '18 at 6:42
1
@Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functionsconstexpr
may move them into the same direction but making such type traits will probably work better in general.
– Scheff
Nov 21 '18 at 6:47
I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.
– Lapys
Nov 21 '18 at 6:37
I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.
– Lapys
Nov 21 '18 at 6:37
1
1
@Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?
– StoryTeller
Nov 21 '18 at 6:40
@Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?
– StoryTeller
Nov 21 '18 at 6:40
Ah, I see. Thanks.
– Lapys
Nov 21 '18 at 6:42
Ah, I see. Thanks.
– Lapys
Nov 21 '18 at 6:42
1
1
@Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions
constexpr
may move them into the same direction but making such type traits will probably work better in general.– Scheff
Nov 21 '18 at 6:47
@Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions
constexpr
may move them into the same direction but making such type traits will probably work better in general.– Scheff
Nov 21 '18 at 6:47
add a comment |
Might
#include <type_traits>
#include <string>
template<typename T>
bool is_string(T)
{
return std::is_constructible<std::string, T>::value;
}
be enough?
add a comment |
Might
#include <type_traits>
#include <string>
template<typename T>
bool is_string(T)
{
return std::is_constructible<std::string, T>::value;
}
be enough?
add a comment |
Might
#include <type_traits>
#include <string>
template<typename T>
bool is_string(T)
{
return std::is_constructible<std::string, T>::value;
}
be enough?
Might
#include <type_traits>
#include <string>
template<typename T>
bool is_string(T)
{
return std::is_constructible<std::string, T>::value;
}
be enough?
answered Nov 21 '18 at 6:37


SwordfishSwordfish
9,42311436
9,42311436
add a comment |
add a comment |
You might directly do:
template <typename T>
constexpr bool isString()
{
return std::is_same<T, const char*>::value
|| std::is_same<T, char*>::value
|| std::is_same<T, std::string>::value;
}
then if you have to set of overloads, you might use SFINAE:
template <typename T>
std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}
template <typename T>
std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}
or if constexpr
(c++17):
template <typename T>
void foo(/**/)
{
if constexpr (isString<T>()) {
/*..*/
} else {
/*..*/
}
}
add a comment |
You might directly do:
template <typename T>
constexpr bool isString()
{
return std::is_same<T, const char*>::value
|| std::is_same<T, char*>::value
|| std::is_same<T, std::string>::value;
}
then if you have to set of overloads, you might use SFINAE:
template <typename T>
std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}
template <typename T>
std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}
or if constexpr
(c++17):
template <typename T>
void foo(/**/)
{
if constexpr (isString<T>()) {
/*..*/
} else {
/*..*/
}
}
add a comment |
You might directly do:
template <typename T>
constexpr bool isString()
{
return std::is_same<T, const char*>::value
|| std::is_same<T, char*>::value
|| std::is_same<T, std::string>::value;
}
then if you have to set of overloads, you might use SFINAE:
template <typename T>
std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}
template <typename T>
std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}
or if constexpr
(c++17):
template <typename T>
void foo(/**/)
{
if constexpr (isString<T>()) {
/*..*/
} else {
/*..*/
}
}
You might directly do:
template <typename T>
constexpr bool isString()
{
return std::is_same<T, const char*>::value
|| std::is_same<T, char*>::value
|| std::is_same<T, std::string>::value;
}
then if you have to set of overloads, you might use SFINAE:
template <typename T>
std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}
template <typename T>
std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}
or if constexpr
(c++17):
template <typename T>
void foo(/**/)
{
if constexpr (isString<T>()) {
/*..*/
} else {
/*..*/
}
}
answered Nov 21 '18 at 9:48
Jarod42Jarod42
116k12102182
116k12102182
add a comment |
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.
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%2f53406038%2fshorthand-for-overloading-multiple-functions%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
For numeric types, there is
std::is_arithmetic
.– halfelf
Nov 21 '18 at 6:03
1
If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.
– StoryTeller
Nov 21 '18 at 6:05
1
@JesperJuhl -
isNumber(std::vector<std::string>{})
?– StoryTeller
Nov 21 '18 at 6:06
1
The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.
– Lapys
Nov 21 '18 at 6:11
1
My point is that you don't need a function. You need a variable template
template<class> bool is_string
and you need to pass it the type of the thing you want to check, not the thing itself.– n.m.
Nov 21 '18 at 10:48