Reputation: 490
I wanted to write a template combination of 2 overloads, as shown in the code below, I wish to do different process on 2 genres of objects. when compile I got these errors:
// Error C2672 'info': no matching overloaded function found
// and
// // Error C2783 'void info(StrType)': could not deduce template argument for '__formal'
code is:
/// With this commented out, compile fails, while with it uncommented, all cals get
// in to this void template.
//template<typename T/*,
//typename = void*/>
//void info(T s) {
//
//}
template <typename StrType,
std::enable_if_t<std::is_convertible_v<std::string, StrType>, bool> = false
>
void info(StrType s) {
std::cout <<"str: "<< s << std::endl;
}
template<typename IntType,
std::enable_if_t<std::is_same_v<
typename std::remove_reference_t<typename std::remove_cv<IntType>> ,
int
>, bool> = false
>
void info(IntType s) {
std::cout <<"int: "<< s + s << std::endl;
}
int main() {
info("31"); // Error C2672 'info': no matching overloaded function found
// and
// // Error C2783 'void info(StrType)': could not deduce template argument for '__formal'
info((int)111); // Same complain as above.
}
I was expecting the output be str: 31 int: 111 but compiling failed, complaining: Error C2672 'info': no matching overloaded function found
Upvotes: 2
Views: 404
Reputation: 36399
Using if constexpr
could make your code simpler, more compact and more importantly more readable:
#include <type_traits>
#include <iostream>
template < typename T >
void info( T s )
{
if constexpr( std::is_convertible_v< T, std::string > )
{
std::cout <<"str: "<< s << std::endl;
}
else if constexpr ( std::is_same_v< std::remove_reference_t< std::remove_cv_t< T > >, int > )
{
std::cout <<"int: "<< s + s << std::endl;
}
else
{
std::cout << "unknown type";
}
}
int main() {
info("31");
info((int)111);
info(1.1);
}
Upvotes: 1
Reputation: 172934
Note that for std::is_convertible
, the 1st template paraemter is From
, the 2nd one is To
, so change the template argument order from
template <typename StrType,
std::enable_if_t<std::is_convertible_v<std::string, StrType>, bool> = false
>
void info(StrType s)
to
template <typename StrType,
std::enable_if_t<std::is_convertible_v<StrType, std::string>, bool> = false
// ^^^^^^^^^^^^^^^^^^^^
>
void info(StrType s)
For the 2nd overload, you should get the type
from std::remove_cv
, not to use itself directly; so change
template<typename IntType,
std::enable_if_t<std::is_same_v<
typename std::remove_reference_t<typename std::remove_cv<IntType>> ,
int
>, bool> = false
>
void info(IntType s) {
to
template<typename IntType,
std::enable_if_t<std::is_same_v<
typename std::remove_reference_t<typename std::remove_cv<IntType>::type> ,
// ^^^^^^
int
>, bool> = false
>
void info(IntType s) {
or (since C++14)
template<typename IntType,
std::enable_if_t<std::is_same_v<
typename std::remove_reference_t<std::remove_cv_t<IntType>> ,
// ^^
int
>, bool> = false
>
void info(IntType s) {
Upvotes: 4