How to compare two typenames for equality in C++?
Clash Royale CLAN TAG#URR8PPP
up vote
21
down vote
favorite
Suppose I have a template of a function, say
template<typename T>
func(T a, T b, ...)
...
for (const auto &single : group)
...
auto c = GivenFunc1(a, b, single, ...);
...
...
However, for T being a special type, say "SpecialType", I want c
being calculated by "GivenFunc2" rather than "GivenFunc1". However, I would not like to write a specialization for "SpecialType", since there will be a huge code duplication. So I want the template function being something like
template<typename T>
func(T a, T b, ...)
...
for (const auto &single : group)
...
auto c = (T == SpecialType) ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
...
...
Of course, this code does not compile since "T == SpecialType" is not valid. So how do I write it in an elegant way?
c++ templates
add a comment |Â
up vote
21
down vote
favorite
Suppose I have a template of a function, say
template<typename T>
func(T a, T b, ...)
...
for (const auto &single : group)
...
auto c = GivenFunc1(a, b, single, ...);
...
...
However, for T being a special type, say "SpecialType", I want c
being calculated by "GivenFunc2" rather than "GivenFunc1". However, I would not like to write a specialization for "SpecialType", since there will be a huge code duplication. So I want the template function being something like
template<typename T>
func(T a, T b, ...)
...
for (const auto &single : group)
...
auto c = (T == SpecialType) ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
...
...
Of course, this code does not compile since "T == SpecialType" is not valid. So how do I write it in an elegant way?
c++ templates
4
What about writing a template specialization instead of?
â ÃÂìýÃÂñ á¿¥Ã栨Â
Aug 19 at 9:20
Possible duplicates: 1 2 3 4
â user202729
Aug 20 at 8:33
add a comment |Â
up vote
21
down vote
favorite
up vote
21
down vote
favorite
Suppose I have a template of a function, say
template<typename T>
func(T a, T b, ...)
...
for (const auto &single : group)
...
auto c = GivenFunc1(a, b, single, ...);
...
...
However, for T being a special type, say "SpecialType", I want c
being calculated by "GivenFunc2" rather than "GivenFunc1". However, I would not like to write a specialization for "SpecialType", since there will be a huge code duplication. So I want the template function being something like
template<typename T>
func(T a, T b, ...)
...
for (const auto &single : group)
...
auto c = (T == SpecialType) ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
...
...
Of course, this code does not compile since "T == SpecialType" is not valid. So how do I write it in an elegant way?
c++ templates
Suppose I have a template of a function, say
template<typename T>
func(T a, T b, ...)
...
for (const auto &single : group)
...
auto c = GivenFunc1(a, b, single, ...);
...
...
However, for T being a special type, say "SpecialType", I want c
being calculated by "GivenFunc2" rather than "GivenFunc1". However, I would not like to write a specialization for "SpecialType", since there will be a huge code duplication. So I want the template function being something like
template<typename T>
func(T a, T b, ...)
...
for (const auto &single : group)
...
auto c = (T == SpecialType) ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
...
...
Of course, this code does not compile since "T == SpecialType" is not valid. So how do I write it in an elegant way?
c++ templates
edited Aug 20 at 5:00
gyre
10.8k11231
10.8k11231
asked Aug 19 at 9:16
dudulu
1115
1115
4
What about writing a template specialization instead of?
â ÃÂìýÃÂñ á¿¥Ã栨Â
Aug 19 at 9:20
Possible duplicates: 1 2 3 4
â user202729
Aug 20 at 8:33
add a comment |Â
4
What about writing a template specialization instead of?
â ÃÂìýÃÂñ á¿¥Ã栨Â
Aug 19 at 9:20
Possible duplicates: 1 2 3 4
â user202729
Aug 20 at 8:33
4
4
What about writing a template specialization instead of?
â ÃÂìýÃÂñ á¿¥Ã栨Â
Aug 19 at 9:20
What about writing a template specialization instead of?
â ÃÂìýÃÂñ á¿¥Ã栨Â
Aug 19 at 9:20
Possible duplicates: 1 2 3 4
â user202729
Aug 20 at 8:33
Possible duplicates: 1 2 3 4
â user202729
Aug 20 at 8:33
add a comment |Â
5 Answers
5
active
oldest
votes
up vote
28
down vote
accepted
It's as simple as:
auto c = std::is_same_v<T, SpecialType> ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
If you can't use C++17, replace std::is_same_v<...>
with std::is_same<...>::value
.
But for this approach to work, both function calls have to be valid for every T
you want to use, even if in reality one of them won't be executed.
If it's not the case, you can resort to if constexpr
:
your_type_here c;
if constexpr (std::is_same_v<T, SpecialType>)
c = GivenFunc2(a, b, single, ...);
else
c = GivenFunc1(a, b, single, ...);
(This works only in C++17.)
7
I'd recommend usingif constexpr
either way. Sure, the compiler should be able to optimise away the check, but checking the validity of the other function call can be costly, especially if it involves additional template instantiations. Also, not usingif constexpr
can be a maintenance problem for those functions: anyone modifying them will have to take into account that they need to be valid even for arguments for which they'll never be called.
â hvd
Aug 19 at 9:29
Great answer, lovely 6 votes. Unfortunately, as much as I would like to see this work on the compiler I'm using, it doesn't work. Is this a C++17 template/function?
â John Law
Aug 19 at 9:46
3
@JohnLaw Yes,std::is_same_v
is C++17. If you don't have it, usestd::is_same<...>::value
instead.if constexpr
is C++17 too, check other answers for alternatives.
â HolyBlackCat
Aug 19 at 9:53
Alright, thanks for clarifying. :-)
â John Law
Aug 19 at 9:56
add a comment |Â
up vote
17
down vote
If you can use C++17, you can achieve the result in a very clean way (with constexpr
and is_same
):
template<typename T>
func(T a, T b, ...)
// ...
if constexpr (std::is_same_v<T, SpecialType>)
// call GivenFunc2
else
// call GivenFunc1
// ...
Pre C++17 you can achieve the same result using techniques such as SFINAE
or "TAG Dispatching".
Additionally, you can just specialize the portion of the code referring to the function call (easy and avoid code duplication).
A short example here:
template <typename T>
struct DispatcherFn
auto operator()(const T&, int)
// call GivenFunc1
;
template <>
struct DispatcherFn<SpecialType>
auto operator()(const SpecialType&, int)
// GivenFunc2
;
template <typename T>
void func(const T& t)
// ... code ...
auto c = DispatcherFn<T>()(t, 49); // specialized call
add a comment |Â
up vote
11
down vote
You can always use template specializations instead of doing type comparisons of template parameters. Here's a simplified, working example:
#include <iostream>
#include <string>
template<typename T>
int GivenFunc1(T a, T b)
std::cout << "GivenFunc1()" << std::endl;
return 0;
template<typename T>
int GivenFunc2(T a, T b)
std::cout << "GivenFunc2()" << std::endl;
return 1;
template<typename T>
void func(T a, T b)
auto c = GivenFunc2(a, b);
std::cout << c << std::endl;
template<>
void func(std::string a, std::string b)
auto c = GivenFunc1(a, b);
std::cout << c << std::endl;
int main()
func(2,3);
std::string a = "Hello";
std::string b = "World";
func(a,b);
See it working online here.
add a comment |Â
up vote
6
down vote
In c++17 the best solution is if constexpr
.
In c++14 this works:
template<class V>
auto dispatch( V const& )
return (auto&&...targets)
return std::get<V>( std::forward_as_tuple( decltype(targets)(targets)... ) );
;
then:
auto c = dispatch( std::is_same<T, SpecialType> )
(
[&](auto&& a, auto&& b) return GivenFunc2(a, b, single...); ,
[&](auto&& a, auto&& b) return GivenFunc1(a, b, single, ...);
)( a, b );
does what you want. (It is also a function which returns a function which returns a function)
Live example.
dispatch
picks one of the two lambdas and returns it at compile time. We then call the picked lambda with a
and b
. So only the valid one is compiled with a type for a
and b
.
add a comment |Â
up vote
1
down vote
Convert GivenFunc1
to a functor and specialise that.
template <class T>
class GivenFunc
X operator()(T a, T b, Y single)
...
template <>
class GivenFunc<SpecialType>
X operator()(SpecialType a, SpecialType b, Y single)
...
Then you can say
auto c = GivenFunc<T>()(a, b, single);
add a comment |Â
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
28
down vote
accepted
It's as simple as:
auto c = std::is_same_v<T, SpecialType> ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
If you can't use C++17, replace std::is_same_v<...>
with std::is_same<...>::value
.
But for this approach to work, both function calls have to be valid for every T
you want to use, even if in reality one of them won't be executed.
If it's not the case, you can resort to if constexpr
:
your_type_here c;
if constexpr (std::is_same_v<T, SpecialType>)
c = GivenFunc2(a, b, single, ...);
else
c = GivenFunc1(a, b, single, ...);
(This works only in C++17.)
7
I'd recommend usingif constexpr
either way. Sure, the compiler should be able to optimise away the check, but checking the validity of the other function call can be costly, especially if it involves additional template instantiations. Also, not usingif constexpr
can be a maintenance problem for those functions: anyone modifying them will have to take into account that they need to be valid even for arguments for which they'll never be called.
â hvd
Aug 19 at 9:29
Great answer, lovely 6 votes. Unfortunately, as much as I would like to see this work on the compiler I'm using, it doesn't work. Is this a C++17 template/function?
â John Law
Aug 19 at 9:46
3
@JohnLaw Yes,std::is_same_v
is C++17. If you don't have it, usestd::is_same<...>::value
instead.if constexpr
is C++17 too, check other answers for alternatives.
â HolyBlackCat
Aug 19 at 9:53
Alright, thanks for clarifying. :-)
â John Law
Aug 19 at 9:56
add a comment |Â
up vote
28
down vote
accepted
It's as simple as:
auto c = std::is_same_v<T, SpecialType> ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
If you can't use C++17, replace std::is_same_v<...>
with std::is_same<...>::value
.
But for this approach to work, both function calls have to be valid for every T
you want to use, even if in reality one of them won't be executed.
If it's not the case, you can resort to if constexpr
:
your_type_here c;
if constexpr (std::is_same_v<T, SpecialType>)
c = GivenFunc2(a, b, single, ...);
else
c = GivenFunc1(a, b, single, ...);
(This works only in C++17.)
7
I'd recommend usingif constexpr
either way. Sure, the compiler should be able to optimise away the check, but checking the validity of the other function call can be costly, especially if it involves additional template instantiations. Also, not usingif constexpr
can be a maintenance problem for those functions: anyone modifying them will have to take into account that they need to be valid even for arguments for which they'll never be called.
â hvd
Aug 19 at 9:29
Great answer, lovely 6 votes. Unfortunately, as much as I would like to see this work on the compiler I'm using, it doesn't work. Is this a C++17 template/function?
â John Law
Aug 19 at 9:46
3
@JohnLaw Yes,std::is_same_v
is C++17. If you don't have it, usestd::is_same<...>::value
instead.if constexpr
is C++17 too, check other answers for alternatives.
â HolyBlackCat
Aug 19 at 9:53
Alright, thanks for clarifying. :-)
â John Law
Aug 19 at 9:56
add a comment |Â
up vote
28
down vote
accepted
up vote
28
down vote
accepted
It's as simple as:
auto c = std::is_same_v<T, SpecialType> ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
If you can't use C++17, replace std::is_same_v<...>
with std::is_same<...>::value
.
But for this approach to work, both function calls have to be valid for every T
you want to use, even if in reality one of them won't be executed.
If it's not the case, you can resort to if constexpr
:
your_type_here c;
if constexpr (std::is_same_v<T, SpecialType>)
c = GivenFunc2(a, b, single, ...);
else
c = GivenFunc1(a, b, single, ...);
(This works only in C++17.)
It's as simple as:
auto c = std::is_same_v<T, SpecialType> ? GivenFunc2(a, b, single, ...)
: GivenFunc1(a, b, single, ...);
If you can't use C++17, replace std::is_same_v<...>
with std::is_same<...>::value
.
But for this approach to work, both function calls have to be valid for every T
you want to use, even if in reality one of them won't be executed.
If it's not the case, you can resort to if constexpr
:
your_type_here c;
if constexpr (std::is_same_v<T, SpecialType>)
c = GivenFunc2(a, b, single, ...);
else
c = GivenFunc1(a, b, single, ...);
(This works only in C++17.)
edited Aug 20 at 9:52
Toby Speight
14.9k133761
14.9k133761
answered Aug 19 at 9:24
HolyBlackCat
13.7k23357
13.7k23357
7
I'd recommend usingif constexpr
either way. Sure, the compiler should be able to optimise away the check, but checking the validity of the other function call can be costly, especially if it involves additional template instantiations. Also, not usingif constexpr
can be a maintenance problem for those functions: anyone modifying them will have to take into account that they need to be valid even for arguments for which they'll never be called.
â hvd
Aug 19 at 9:29
Great answer, lovely 6 votes. Unfortunately, as much as I would like to see this work on the compiler I'm using, it doesn't work. Is this a C++17 template/function?
â John Law
Aug 19 at 9:46
3
@JohnLaw Yes,std::is_same_v
is C++17. If you don't have it, usestd::is_same<...>::value
instead.if constexpr
is C++17 too, check other answers for alternatives.
â HolyBlackCat
Aug 19 at 9:53
Alright, thanks for clarifying. :-)
â John Law
Aug 19 at 9:56
add a comment |Â
7
I'd recommend usingif constexpr
either way. Sure, the compiler should be able to optimise away the check, but checking the validity of the other function call can be costly, especially if it involves additional template instantiations. Also, not usingif constexpr
can be a maintenance problem for those functions: anyone modifying them will have to take into account that they need to be valid even for arguments for which they'll never be called.
â hvd
Aug 19 at 9:29
Great answer, lovely 6 votes. Unfortunately, as much as I would like to see this work on the compiler I'm using, it doesn't work. Is this a C++17 template/function?
â John Law
Aug 19 at 9:46
3
@JohnLaw Yes,std::is_same_v
is C++17. If you don't have it, usestd::is_same<...>::value
instead.if constexpr
is C++17 too, check other answers for alternatives.
â HolyBlackCat
Aug 19 at 9:53
Alright, thanks for clarifying. :-)
â John Law
Aug 19 at 9:56
7
7
I'd recommend using
if constexpr
either way. Sure, the compiler should be able to optimise away the check, but checking the validity of the other function call can be costly, especially if it involves additional template instantiations. Also, not using if constexpr
can be a maintenance problem for those functions: anyone modifying them will have to take into account that they need to be valid even for arguments for which they'll never be called.â hvd
Aug 19 at 9:29
I'd recommend using
if constexpr
either way. Sure, the compiler should be able to optimise away the check, but checking the validity of the other function call can be costly, especially if it involves additional template instantiations. Also, not using if constexpr
can be a maintenance problem for those functions: anyone modifying them will have to take into account that they need to be valid even for arguments for which they'll never be called.â hvd
Aug 19 at 9:29
Great answer, lovely 6 votes. Unfortunately, as much as I would like to see this work on the compiler I'm using, it doesn't work. Is this a C++17 template/function?
â John Law
Aug 19 at 9:46
Great answer, lovely 6 votes. Unfortunately, as much as I would like to see this work on the compiler I'm using, it doesn't work. Is this a C++17 template/function?
â John Law
Aug 19 at 9:46
3
3
@JohnLaw Yes,
std::is_same_v
is C++17. If you don't have it, use std::is_same<...>::value
instead. if constexpr
is C++17 too, check other answers for alternatives.â HolyBlackCat
Aug 19 at 9:53
@JohnLaw Yes,
std::is_same_v
is C++17. If you don't have it, use std::is_same<...>::value
instead. if constexpr
is C++17 too, check other answers for alternatives.â HolyBlackCat
Aug 19 at 9:53
Alright, thanks for clarifying. :-)
â John Law
Aug 19 at 9:56
Alright, thanks for clarifying. :-)
â John Law
Aug 19 at 9:56
add a comment |Â
up vote
17
down vote
If you can use C++17, you can achieve the result in a very clean way (with constexpr
and is_same
):
template<typename T>
func(T a, T b, ...)
// ...
if constexpr (std::is_same_v<T, SpecialType>)
// call GivenFunc2
else
// call GivenFunc1
// ...
Pre C++17 you can achieve the same result using techniques such as SFINAE
or "TAG Dispatching".
Additionally, you can just specialize the portion of the code referring to the function call (easy and avoid code duplication).
A short example here:
template <typename T>
struct DispatcherFn
auto operator()(const T&, int)
// call GivenFunc1
;
template <>
struct DispatcherFn<SpecialType>
auto operator()(const SpecialType&, int)
// GivenFunc2
;
template <typename T>
void func(const T& t)
// ... code ...
auto c = DispatcherFn<T>()(t, 49); // specialized call
add a comment |Â
up vote
17
down vote
If you can use C++17, you can achieve the result in a very clean way (with constexpr
and is_same
):
template<typename T>
func(T a, T b, ...)
// ...
if constexpr (std::is_same_v<T, SpecialType>)
// call GivenFunc2
else
// call GivenFunc1
// ...
Pre C++17 you can achieve the same result using techniques such as SFINAE
or "TAG Dispatching".
Additionally, you can just specialize the portion of the code referring to the function call (easy and avoid code duplication).
A short example here:
template <typename T>
struct DispatcherFn
auto operator()(const T&, int)
// call GivenFunc1
;
template <>
struct DispatcherFn<SpecialType>
auto operator()(const SpecialType&, int)
// GivenFunc2
;
template <typename T>
void func(const T& t)
// ... code ...
auto c = DispatcherFn<T>()(t, 49); // specialized call
add a comment |Â
up vote
17
down vote
up vote
17
down vote
If you can use C++17, you can achieve the result in a very clean way (with constexpr
and is_same
):
template<typename T>
func(T a, T b, ...)
// ...
if constexpr (std::is_same_v<T, SpecialType>)
// call GivenFunc2
else
// call GivenFunc1
// ...
Pre C++17 you can achieve the same result using techniques such as SFINAE
or "TAG Dispatching".
Additionally, you can just specialize the portion of the code referring to the function call (easy and avoid code duplication).
A short example here:
template <typename T>
struct DispatcherFn
auto operator()(const T&, int)
// call GivenFunc1
;
template <>
struct DispatcherFn<SpecialType>
auto operator()(const SpecialType&, int)
// GivenFunc2
;
template <typename T>
void func(const T& t)
// ... code ...
auto c = DispatcherFn<T>()(t, 49); // specialized call
If you can use C++17, you can achieve the result in a very clean way (with constexpr
and is_same
):
template<typename T>
func(T a, T b, ...)
// ...
if constexpr (std::is_same_v<T, SpecialType>)
// call GivenFunc2
else
// call GivenFunc1
// ...
Pre C++17 you can achieve the same result using techniques such as SFINAE
or "TAG Dispatching".
Additionally, you can just specialize the portion of the code referring to the function call (easy and avoid code duplication).
A short example here:
template <typename T>
struct DispatcherFn
auto operator()(const T&, int)
// call GivenFunc1
;
template <>
struct DispatcherFn<SpecialType>
auto operator()(const SpecialType&, int)
// GivenFunc2
;
template <typename T>
void func(const T& t)
// ... code ...
auto c = DispatcherFn<T>()(t, 49); // specialized call
edited Aug 20 at 0:38
answered Aug 19 at 9:30
Biagio Festa
4,53121035
4,53121035
add a comment |Â
add a comment |Â
up vote
11
down vote
You can always use template specializations instead of doing type comparisons of template parameters. Here's a simplified, working example:
#include <iostream>
#include <string>
template<typename T>
int GivenFunc1(T a, T b)
std::cout << "GivenFunc1()" << std::endl;
return 0;
template<typename T>
int GivenFunc2(T a, T b)
std::cout << "GivenFunc2()" << std::endl;
return 1;
template<typename T>
void func(T a, T b)
auto c = GivenFunc2(a, b);
std::cout << c << std::endl;
template<>
void func(std::string a, std::string b)
auto c = GivenFunc1(a, b);
std::cout << c << std::endl;
int main()
func(2,3);
std::string a = "Hello";
std::string b = "World";
func(a,b);
See it working online here.
add a comment |Â
up vote
11
down vote
You can always use template specializations instead of doing type comparisons of template parameters. Here's a simplified, working example:
#include <iostream>
#include <string>
template<typename T>
int GivenFunc1(T a, T b)
std::cout << "GivenFunc1()" << std::endl;
return 0;
template<typename T>
int GivenFunc2(T a, T b)
std::cout << "GivenFunc2()" << std::endl;
return 1;
template<typename T>
void func(T a, T b)
auto c = GivenFunc2(a, b);
std::cout << c << std::endl;
template<>
void func(std::string a, std::string b)
auto c = GivenFunc1(a, b);
std::cout << c << std::endl;
int main()
func(2,3);
std::string a = "Hello";
std::string b = "World";
func(a,b);
See it working online here.
add a comment |Â
up vote
11
down vote
up vote
11
down vote
You can always use template specializations instead of doing type comparisons of template parameters. Here's a simplified, working example:
#include <iostream>
#include <string>
template<typename T>
int GivenFunc1(T a, T b)
std::cout << "GivenFunc1()" << std::endl;
return 0;
template<typename T>
int GivenFunc2(T a, T b)
std::cout << "GivenFunc2()" << std::endl;
return 1;
template<typename T>
void func(T a, T b)
auto c = GivenFunc2(a, b);
std::cout << c << std::endl;
template<>
void func(std::string a, std::string b)
auto c = GivenFunc1(a, b);
std::cout << c << std::endl;
int main()
func(2,3);
std::string a = "Hello";
std::string b = "World";
func(a,b);
See it working online here.
You can always use template specializations instead of doing type comparisons of template parameters. Here's a simplified, working example:
#include <iostream>
#include <string>
template<typename T>
int GivenFunc1(T a, T b)
std::cout << "GivenFunc1()" << std::endl;
return 0;
template<typename T>
int GivenFunc2(T a, T b)
std::cout << "GivenFunc2()" << std::endl;
return 1;
template<typename T>
void func(T a, T b)
auto c = GivenFunc2(a, b);
std::cout << c << std::endl;
template<>
void func(std::string a, std::string b)
auto c = GivenFunc1(a, b);
std::cout << c << std::endl;
int main()
func(2,3);
std::string a = "Hello";
std::string b = "World";
func(a,b);
See it working online here.
answered Aug 19 at 9:35
ÃÂìýÃÂñ á¿¥Ã栨Â
70k869132
70k869132
add a comment |Â
add a comment |Â
up vote
6
down vote
In c++17 the best solution is if constexpr
.
In c++14 this works:
template<class V>
auto dispatch( V const& )
return (auto&&...targets)
return std::get<V>( std::forward_as_tuple( decltype(targets)(targets)... ) );
;
then:
auto c = dispatch( std::is_same<T, SpecialType> )
(
[&](auto&& a, auto&& b) return GivenFunc2(a, b, single...); ,
[&](auto&& a, auto&& b) return GivenFunc1(a, b, single, ...);
)( a, b );
does what you want. (It is also a function which returns a function which returns a function)
Live example.
dispatch
picks one of the two lambdas and returns it at compile time. We then call the picked lambda with a
and b
. So only the valid one is compiled with a type for a
and b
.
add a comment |Â
up vote
6
down vote
In c++17 the best solution is if constexpr
.
In c++14 this works:
template<class V>
auto dispatch( V const& )
return (auto&&...targets)
return std::get<V>( std::forward_as_tuple( decltype(targets)(targets)... ) );
;
then:
auto c = dispatch( std::is_same<T, SpecialType> )
(
[&](auto&& a, auto&& b) return GivenFunc2(a, b, single...); ,
[&](auto&& a, auto&& b) return GivenFunc1(a, b, single, ...);
)( a, b );
does what you want. (It is also a function which returns a function which returns a function)
Live example.
dispatch
picks one of the two lambdas and returns it at compile time. We then call the picked lambda with a
and b
. So only the valid one is compiled with a type for a
and b
.
add a comment |Â
up vote
6
down vote
up vote
6
down vote
In c++17 the best solution is if constexpr
.
In c++14 this works:
template<class V>
auto dispatch( V const& )
return (auto&&...targets)
return std::get<V>( std::forward_as_tuple( decltype(targets)(targets)... ) );
;
then:
auto c = dispatch( std::is_same<T, SpecialType> )
(
[&](auto&& a, auto&& b) return GivenFunc2(a, b, single...); ,
[&](auto&& a, auto&& b) return GivenFunc1(a, b, single, ...);
)( a, b );
does what you want. (It is also a function which returns a function which returns a function)
Live example.
dispatch
picks one of the two lambdas and returns it at compile time. We then call the picked lambda with a
and b
. So only the valid one is compiled with a type for a
and b
.
In c++17 the best solution is if constexpr
.
In c++14 this works:
template<class V>
auto dispatch( V const& )
return (auto&&...targets)
return std::get<V>( std::forward_as_tuple( decltype(targets)(targets)... ) );
;
then:
auto c = dispatch( std::is_same<T, SpecialType> )
(
[&](auto&& a, auto&& b) return GivenFunc2(a, b, single...); ,
[&](auto&& a, auto&& b) return GivenFunc1(a, b, single, ...);
)( a, b );
does what you want. (It is also a function which returns a function which returns a function)
Live example.
dispatch
picks one of the two lambdas and returns it at compile time. We then call the picked lambda with a
and b
. So only the valid one is compiled with a type for a
and b
.
edited Aug 20 at 19:41
answered Aug 19 at 11:21
Yakk - Adam Nevraumont
169k18172349
169k18172349
add a comment |Â
add a comment |Â
up vote
1
down vote
Convert GivenFunc1
to a functor and specialise that.
template <class T>
class GivenFunc
X operator()(T a, T b, Y single)
...
template <>
class GivenFunc<SpecialType>
X operator()(SpecialType a, SpecialType b, Y single)
...
Then you can say
auto c = GivenFunc<T>()(a, b, single);
add a comment |Â
up vote
1
down vote
Convert GivenFunc1
to a functor and specialise that.
template <class T>
class GivenFunc
X operator()(T a, T b, Y single)
...
template <>
class GivenFunc<SpecialType>
X operator()(SpecialType a, SpecialType b, Y single)
...
Then you can say
auto c = GivenFunc<T>()(a, b, single);
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Convert GivenFunc1
to a functor and specialise that.
template <class T>
class GivenFunc
X operator()(T a, T b, Y single)
...
template <>
class GivenFunc<SpecialType>
X operator()(SpecialType a, SpecialType b, Y single)
...
Then you can say
auto c = GivenFunc<T>()(a, b, single);
Convert GivenFunc1
to a functor and specialise that.
template <class T>
class GivenFunc
X operator()(T a, T b, Y single)
...
template <>
class GivenFunc<SpecialType>
X operator()(SpecialType a, SpecialType b, Y single)
...
Then you can say
auto c = GivenFunc<T>()(a, b, single);
answered Aug 19 at 9:30
john
32.8k12645
32.8k12645
add a comment |Â
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51916198%2fhow-to-compare-two-typenames-for-equality-in-c%23new-answer', 'question_page');
);
Post as a guest
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
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
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
4
What about writing a template specialization instead of?
â ÃÂìýÃÂñ á¿¥Ã栨Â
Aug 19 at 9:20
Possible duplicates: 1 2 3 4
â user202729
Aug 20 at 8:33