How can I check type T is among parameter pack Ts…?How can I profile C++ code running on Linux?Is there a standard sign function (signum, sgn) in C/C++?Check if a string contains a string in C++Pretty-print C++ STL containersExpanding parameter pack containing initializer_list to constructorWhy std::fstream returns void instead of boolBool sorted insert function with check if int already exist in listType checking template class parametersCould not deduce template argument for std::function from std::bindDoes the C++ standard allow for an uninitialized bool to crash a program?
Why will we fail creating a self sustaining off world colony?
Identifying positions of the last TRUEs in a sequence of TRUEs and FALSEs
Five 5-cent coins touching each other
How to stop QGIS from looking for the wrong PostgreSQL host address in an existing workproject?
Odd PCB Layout for Voltage Regulator
Basic calculations in PGF/TikZ for loop
German idiomatic equivalents of 能骗就骗 (if you can cheat, then cheat)
iMac 2019: Can I mix the old modules with the new ones when upgrading RAM?
Drawing a sigmoid function and its derivative in tikz
Is it advisable to inform the CEO about his brother accessing his office?
How far can gerrymandering go?
What verb goes with "coup"?
What is this fluorinated organic substance?
Installed software from source, how to say yum not to install it from package?
Why would Dementors torture a Death Eater if they are loyal to Voldemort?
What was the point of separating stdout and stderr?
Active wildlife outside the window- Good or Bad for Cat psychology?
What are the children of two Muggle-borns called?
What does this Pokemon Trainer mean by saying the player is "SHELLOS"?
What's the lunar calendar of two moons
Are you required to spend hit dice to take a short rest?
Why should I allow multiple IP addresses on a website for a single session?
How soon after takeoff can you recline your airplane seat?
How to count the number of bytes in a file, grouping the same bytes?
How can I check type T is among parameter pack Ts…?
How can I profile C++ code running on Linux?Is there a standard sign function (signum, sgn) in C/C++?Check if a string contains a string in C++Pretty-print C++ STL containersExpanding parameter pack containing initializer_list to constructorWhy std::fstream returns void instead of boolBool sorted insert function with check if int already exist in listType checking template class parametersCould not deduce template argument for std::function from std::bindDoes the C++ standard allow for an uninitialized bool to crash a program?
I want to write a function to return true if T
is one of Ts...
template<class T, class... Ts>
bool is_one_of<T, Ts...>();
For example, is_one_of<int, double, int, float>
returns true
, and is_one_of<int, double, std::string, bool, bool>
returns false
.
My own implementation is
template<class T1, class T2>
bool is_one_of<T1, T2>()
return std::is_same<T1, T2>;
template<class T1, class T2, class... Ts>
bool is_one_of<T1, T2, Ts...>()
if (std::is_same<T1, T2>)
return true;
else
return is_one_of<T1, Ts...>();
This check seems common to me so I wonder if there's already such a function in the standard library.
c++ variadic-templates
add a comment |
I want to write a function to return true if T
is one of Ts...
template<class T, class... Ts>
bool is_one_of<T, Ts...>();
For example, is_one_of<int, double, int, float>
returns true
, and is_one_of<int, double, std::string, bool, bool>
returns false
.
My own implementation is
template<class T1, class T2>
bool is_one_of<T1, T2>()
return std::is_same<T1, T2>;
template<class T1, class T2, class... Ts>
bool is_one_of<T1, T2, Ts...>()
if (std::is_same<T1, T2>)
return true;
else
return is_one_of<T1, Ts...>();
This check seems common to me so I wonder if there's already such a function in the standard library.
c++ variadic-templates
add a comment |
I want to write a function to return true if T
is one of Ts...
template<class T, class... Ts>
bool is_one_of<T, Ts...>();
For example, is_one_of<int, double, int, float>
returns true
, and is_one_of<int, double, std::string, bool, bool>
returns false
.
My own implementation is
template<class T1, class T2>
bool is_one_of<T1, T2>()
return std::is_same<T1, T2>;
template<class T1, class T2, class... Ts>
bool is_one_of<T1, T2, Ts...>()
if (std::is_same<T1, T2>)
return true;
else
return is_one_of<T1, Ts...>();
This check seems common to me so I wonder if there's already such a function in the standard library.
c++ variadic-templates
I want to write a function to return true if T
is one of Ts...
template<class T, class... Ts>
bool is_one_of<T, Ts...>();
For example, is_one_of<int, double, int, float>
returns true
, and is_one_of<int, double, std::string, bool, bool>
returns false
.
My own implementation is
template<class T1, class T2>
bool is_one_of<T1, T2>()
return std::is_same<T1, T2>;
template<class T1, class T2, class... Ts>
bool is_one_of<T1, T2, Ts...>()
if (std::is_same<T1, T2>)
return true;
else
return is_one_of<T1, Ts...>();
This check seems common to me so I wonder if there's already such a function in the standard library.
c++ variadic-templates
c++ variadic-templates
edited Jun 25 at 8:56
Uwe Keim
28k32 gold badges141 silver badges223 bronze badges
28k32 gold badges141 silver badges223 bronze badges
asked Jun 23 at 0:00
Yixing LiuYixing Liu
5216 silver badges19 bronze badges
5216 silver badges19 bronze badges
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
In your own implementation, one issue is that C++ doesn't allow partial specialization on function templates.
You can use the fold expression (which is introduced in C++17) instead of recursive function call.
template<class T1, class... Ts>
constexpr bool is_one_of() noexcept
If you are using C++11 where fold expression and std::disjunction
are not available, you can implement is_one_of
like this:
template<class...> struct is_one_of: std::false_type ;
template<class T1, class T2> struct is_one_of<T1, T2>: std::is_same<T1, T2> ;
template<class T1, class T2, class... Ts> struct is_one_of<T1, T2, Ts...>: std::conditional<std::is_same<T1, T2>::value, std::is_same<T1, T2>, is_one_of<T1, Ts...>>::type ;
2
Could also be a variable and not a function :)
– Rakete1111
Jun 23 at 8:36
add a comment |
You can also use std::disjunction
to avoid unnecessary template instantiation:
template <class T0, class... Ts>
constexpr bool is_one_of = std::disjunction_v<std::is_same<T0, Ts>...>;
After a matching type is found, the remaining templates are not instantiated. In contrast, a fold expression instantiates all of them. This can make a significant difference in compile time depending on your use case.
Actually, OP's implementation is very similar to the implementation ofstd::disjunction
– Shaoyu Chen
Jun 23 at 1:22
3
@ShaoyuChen Yep. The idea is that "there's already such a function in the standard library" as OP wondered
– L. F.
Jun 23 at 1:22
add a comment |
Check if type T is among parameter pack Ts:
template<class T0, class... Ts>
constexpr bool is_one_of = (std::is_same<T0, Ts>||...);
template variable.
Alternative:
template<class T0, class... Ts>
constexpr std::integral_constant<bool,(std::is_same<T0, Ts>||...)> is_one_of = ;
Which has subtle differences.
add a comment |
The other answers show several correct solutions to solve this specific problem in a clean and concise way. Here is a solution that is not recommended for this specific problem, but demonstrates an alternate technique: In constexpr
functions you can use plain for loops and simple logic in order to compute results at compile time. This allows to get rid of the recursion and the attempted partial template specialization of OP's code.
#include <initializer_list>
#include <type_traits>
template<class T, class... Ts>
constexpr bool is_one_of()
bool ret = false;
for(bool is_this_one : std::is_same<T, Ts>::value...) = is_this_one;// alternative style: `if(is_this_one) return true;`
return ret;
static_assert(is_one_of<int, double, int, float>(), "");
static_assert(!is_one_of<int, double, char, bool, bool>(), "");
Requires at least C++14.
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%2f56720024%2fhow-can-i-check-type-t-is-among-parameter-pack-ts%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
In your own implementation, one issue is that C++ doesn't allow partial specialization on function templates.
You can use the fold expression (which is introduced in C++17) instead of recursive function call.
template<class T1, class... Ts>
constexpr bool is_one_of() noexcept
If you are using C++11 where fold expression and std::disjunction
are not available, you can implement is_one_of
like this:
template<class...> struct is_one_of: std::false_type ;
template<class T1, class T2> struct is_one_of<T1, T2>: std::is_same<T1, T2> ;
template<class T1, class T2, class... Ts> struct is_one_of<T1, T2, Ts...>: std::conditional<std::is_same<T1, T2>::value, std::is_same<T1, T2>, is_one_of<T1, Ts...>>::type ;
2
Could also be a variable and not a function :)
– Rakete1111
Jun 23 at 8:36
add a comment |
In your own implementation, one issue is that C++ doesn't allow partial specialization on function templates.
You can use the fold expression (which is introduced in C++17) instead of recursive function call.
template<class T1, class... Ts>
constexpr bool is_one_of() noexcept
If you are using C++11 where fold expression and std::disjunction
are not available, you can implement is_one_of
like this:
template<class...> struct is_one_of: std::false_type ;
template<class T1, class T2> struct is_one_of<T1, T2>: std::is_same<T1, T2> ;
template<class T1, class T2, class... Ts> struct is_one_of<T1, T2, Ts...>: std::conditional<std::is_same<T1, T2>::value, std::is_same<T1, T2>, is_one_of<T1, Ts...>>::type ;
2
Could also be a variable and not a function :)
– Rakete1111
Jun 23 at 8:36
add a comment |
In your own implementation, one issue is that C++ doesn't allow partial specialization on function templates.
You can use the fold expression (which is introduced in C++17) instead of recursive function call.
template<class T1, class... Ts>
constexpr bool is_one_of() noexcept
If you are using C++11 where fold expression and std::disjunction
are not available, you can implement is_one_of
like this:
template<class...> struct is_one_of: std::false_type ;
template<class T1, class T2> struct is_one_of<T1, T2>: std::is_same<T1, T2> ;
template<class T1, class T2, class... Ts> struct is_one_of<T1, T2, Ts...>: std::conditional<std::is_same<T1, T2>::value, std::is_same<T1, T2>, is_one_of<T1, Ts...>>::type ;
In your own implementation, one issue is that C++ doesn't allow partial specialization on function templates.
You can use the fold expression (which is introduced in C++17) instead of recursive function call.
template<class T1, class... Ts>
constexpr bool is_one_of() noexcept
If you are using C++11 where fold expression and std::disjunction
are not available, you can implement is_one_of
like this:
template<class...> struct is_one_of: std::false_type ;
template<class T1, class T2> struct is_one_of<T1, T2>: std::is_same<T1, T2> ;
template<class T1, class T2, class... Ts> struct is_one_of<T1, T2, Ts...>: std::conditional<std::is_same<T1, T2>::value, std::is_same<T1, T2>, is_one_of<T1, Ts...>>::type ;
edited Jun 23 at 23:29
answered Jun 23 at 0:36
Shaoyu ChenShaoyu Chen
3361 silver badge5 bronze badges
3361 silver badge5 bronze badges
2
Could also be a variable and not a function :)
– Rakete1111
Jun 23 at 8:36
add a comment |
2
Could also be a variable and not a function :)
– Rakete1111
Jun 23 at 8:36
2
2
Could also be a variable and not a function :)
– Rakete1111
Jun 23 at 8:36
Could also be a variable and not a function :)
– Rakete1111
Jun 23 at 8:36
add a comment |
You can also use std::disjunction
to avoid unnecessary template instantiation:
template <class T0, class... Ts>
constexpr bool is_one_of = std::disjunction_v<std::is_same<T0, Ts>...>;
After a matching type is found, the remaining templates are not instantiated. In contrast, a fold expression instantiates all of them. This can make a significant difference in compile time depending on your use case.
Actually, OP's implementation is very similar to the implementation ofstd::disjunction
– Shaoyu Chen
Jun 23 at 1:22
3
@ShaoyuChen Yep. The idea is that "there's already such a function in the standard library" as OP wondered
– L. F.
Jun 23 at 1:22
add a comment |
You can also use std::disjunction
to avoid unnecessary template instantiation:
template <class T0, class... Ts>
constexpr bool is_one_of = std::disjunction_v<std::is_same<T0, Ts>...>;
After a matching type is found, the remaining templates are not instantiated. In contrast, a fold expression instantiates all of them. This can make a significant difference in compile time depending on your use case.
Actually, OP's implementation is very similar to the implementation ofstd::disjunction
– Shaoyu Chen
Jun 23 at 1:22
3
@ShaoyuChen Yep. The idea is that "there's already such a function in the standard library" as OP wondered
– L. F.
Jun 23 at 1:22
add a comment |
You can also use std::disjunction
to avoid unnecessary template instantiation:
template <class T0, class... Ts>
constexpr bool is_one_of = std::disjunction_v<std::is_same<T0, Ts>...>;
After a matching type is found, the remaining templates are not instantiated. In contrast, a fold expression instantiates all of them. This can make a significant difference in compile time depending on your use case.
You can also use std::disjunction
to avoid unnecessary template instantiation:
template <class T0, class... Ts>
constexpr bool is_one_of = std::disjunction_v<std::is_same<T0, Ts>...>;
After a matching type is found, the remaining templates are not instantiated. In contrast, a fold expression instantiates all of them. This can make a significant difference in compile time depending on your use case.
edited Jun 24 at 8:25
answered Jun 23 at 1:00
L. F.L. F.
4,2033 gold badges16 silver badges40 bronze badges
4,2033 gold badges16 silver badges40 bronze badges
Actually, OP's implementation is very similar to the implementation ofstd::disjunction
– Shaoyu Chen
Jun 23 at 1:22
3
@ShaoyuChen Yep. The idea is that "there's already such a function in the standard library" as OP wondered
– L. F.
Jun 23 at 1:22
add a comment |
Actually, OP's implementation is very similar to the implementation ofstd::disjunction
– Shaoyu Chen
Jun 23 at 1:22
3
@ShaoyuChen Yep. The idea is that "there's already such a function in the standard library" as OP wondered
– L. F.
Jun 23 at 1:22
Actually, OP's implementation is very similar to the implementation of
std::disjunction
– Shaoyu Chen
Jun 23 at 1:22
Actually, OP's implementation is very similar to the implementation of
std::disjunction
– Shaoyu Chen
Jun 23 at 1:22
3
3
@ShaoyuChen Yep. The idea is that "there's already such a function in the standard library" as OP wondered
– L. F.
Jun 23 at 1:22
@ShaoyuChen Yep. The idea is that "there's already such a function in the standard library" as OP wondered
– L. F.
Jun 23 at 1:22
add a comment |
Check if type T is among parameter pack Ts:
template<class T0, class... Ts>
constexpr bool is_one_of = (std::is_same<T0, Ts>||...);
template variable.
Alternative:
template<class T0, class... Ts>
constexpr std::integral_constant<bool,(std::is_same<T0, Ts>||...)> is_one_of = ;
Which has subtle differences.
add a comment |
Check if type T is among parameter pack Ts:
template<class T0, class... Ts>
constexpr bool is_one_of = (std::is_same<T0, Ts>||...);
template variable.
Alternative:
template<class T0, class... Ts>
constexpr std::integral_constant<bool,(std::is_same<T0, Ts>||...)> is_one_of = ;
Which has subtle differences.
add a comment |
Check if type T is among parameter pack Ts:
template<class T0, class... Ts>
constexpr bool is_one_of = (std::is_same<T0, Ts>||...);
template variable.
Alternative:
template<class T0, class... Ts>
constexpr std::integral_constant<bool,(std::is_same<T0, Ts>||...)> is_one_of = ;
Which has subtle differences.
Check if type T is among parameter pack Ts:
template<class T0, class... Ts>
constexpr bool is_one_of = (std::is_same<T0, Ts>||...);
template variable.
Alternative:
template<class T0, class... Ts>
constexpr std::integral_constant<bool,(std::is_same<T0, Ts>||...)> is_one_of = ;
Which has subtle differences.
edited Jun 23 at 2:23
answered Jun 23 at 0:17
Yakk - Adam NevraumontYakk - Adam Nevraumont
194k21 gold badges211 silver badges401 bronze badges
194k21 gold badges211 silver badges401 bronze badges
add a comment |
add a comment |
The other answers show several correct solutions to solve this specific problem in a clean and concise way. Here is a solution that is not recommended for this specific problem, but demonstrates an alternate technique: In constexpr
functions you can use plain for loops and simple logic in order to compute results at compile time. This allows to get rid of the recursion and the attempted partial template specialization of OP's code.
#include <initializer_list>
#include <type_traits>
template<class T, class... Ts>
constexpr bool is_one_of()
bool ret = false;
for(bool is_this_one : std::is_same<T, Ts>::value...) = is_this_one;// alternative style: `if(is_this_one) return true;`
return ret;
static_assert(is_one_of<int, double, int, float>(), "");
static_assert(!is_one_of<int, double, char, bool, bool>(), "");
Requires at least C++14.
add a comment |
The other answers show several correct solutions to solve this specific problem in a clean and concise way. Here is a solution that is not recommended for this specific problem, but demonstrates an alternate technique: In constexpr
functions you can use plain for loops and simple logic in order to compute results at compile time. This allows to get rid of the recursion and the attempted partial template specialization of OP's code.
#include <initializer_list>
#include <type_traits>
template<class T, class... Ts>
constexpr bool is_one_of()
bool ret = false;
for(bool is_this_one : std::is_same<T, Ts>::value...) = is_this_one;// alternative style: `if(is_this_one) return true;`
return ret;
static_assert(is_one_of<int, double, int, float>(), "");
static_assert(!is_one_of<int, double, char, bool, bool>(), "");
Requires at least C++14.
add a comment |
The other answers show several correct solutions to solve this specific problem in a clean and concise way. Here is a solution that is not recommended for this specific problem, but demonstrates an alternate technique: In constexpr
functions you can use plain for loops and simple logic in order to compute results at compile time. This allows to get rid of the recursion and the attempted partial template specialization of OP's code.
#include <initializer_list>
#include <type_traits>
template<class T, class... Ts>
constexpr bool is_one_of()
bool ret = false;
for(bool is_this_one : std::is_same<T, Ts>::value...) = is_this_one;// alternative style: `if(is_this_one) return true;`
return ret;
static_assert(is_one_of<int, double, int, float>(), "");
static_assert(!is_one_of<int, double, char, bool, bool>(), "");
Requires at least C++14.
The other answers show several correct solutions to solve this specific problem in a clean and concise way. Here is a solution that is not recommended for this specific problem, but demonstrates an alternate technique: In constexpr
functions you can use plain for loops and simple logic in order to compute results at compile time. This allows to get rid of the recursion and the attempted partial template specialization of OP's code.
#include <initializer_list>
#include <type_traits>
template<class T, class... Ts>
constexpr bool is_one_of()
bool ret = false;
for(bool is_this_one : std::is_same<T, Ts>::value...) = is_this_one;// alternative style: `if(is_this_one) return true;`
return ret;
static_assert(is_one_of<int, double, int, float>(), "");
static_assert(!is_one_of<int, double, char, bool, bool>(), "");
Requires at least C++14.
edited Jun 25 at 10:21
answered Jun 25 at 8:55
JuliusJulius
1,3686 silver badges13 bronze badges
1,3686 silver badges13 bronze badges
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%2f56720024%2fhow-can-i-check-type-t-is-among-parameter-pack-ts%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