Ηello
I write a code in C++ using templates and I try to implement a SFINAE what is fired when operator +
is not supported.
I write the following code
#include <iostream>
#include <type_traits>
class B
{
};
template<typename T1,typename T2>
struct IsSameT :std::false_type
{
//static constexpr bool value = false;
};
template<typename T>
struct IsSameT<T,T> :std::true_type
{
//static constexpr bool value = true;
};
template<typename T1, typename T2>
struct HasPlusT
{
private:
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
template<typename U1, typename = decltype(T1_t() + T2_t())>
static char test(void *);
template<typename>
static long test(...);
public:
static constexpr bool value = IsSameT<decltype(test<T1,T2>(nullptr)),char>::value;
};
template<typename T1,typename T2, bool = HasPlusT<T1,T2>::value>
struct PlusResultT
{
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
using Type = decltype(T1_t() + T2_t());
};
template<typename T1,typename T2>
struct PlusResultT<T1,T2,false>
{
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
using Type = decltype(T1_t() + T2_t());
};
int main()
{
constexpr bool value = HasPlusT<B,B>::value;
return 0;
}
I expect the constexpr bool value = HasPlusT<B,B>::value
to return false
but an error is generated
What is wrong in implementation?
Class B has not an operator + and I expect that the constexpr bool value = >HasPlusT::value returns true. However a compilation error is generated no match for 'operator+' (operand types are 'HasPlusT::T1_t {aka B}' and >'HasPlusT::T2_t {aka B}') Demo.cpp /Demo C/C++ >Problem
==============================================
New implementation to support class templates. Why the following implementatio fail to verify that operator + exists
#include <iostream>
#include <type_traits>
#include <array>
#include <vector>
#include <utility>
template<typename T1,typename T2>
struct IsSameT :std::false_type
{
//static constexpr bool value = false;
};
template<typename T>
struct IsSameT<T,T> :std::true_type
{
//static constexpr bool value = true;
};
template<typename T, typename U>
struct IsFuntamentalHelper : IsSameT<T,U>
{
//static constexpr bool value = IsSameT<T,U>::value;
};
template<typename T>
struct IsFundamentalT : std::false_type
{
//static constexpr boo value = std::false_type;
};
template<>
struct IsFundamentalT<int> : IsFuntamentalHelper<int,int>
{
};
template<>
struct IsFundamentalT<float> : IsFuntamentalHelper<float,float>
{
};
template<>
struct IsFundamentalT<double> : IsFuntamentalHelper<double,double>
{
};
template<>
struct IsFundamentalT<long>: IsFuntamentalHelper<long,long>
{
};
template<typename T>
using enable_if_t = typename std::enable_if<IsFundamentalT<T>::value, T>::type;
template<typename T>
class A
{
public:
template<typename = enable_if_t<T>>
operator T()
{
return t ;
}
A<T>():t()
{
}
template<typename = enable_if_t<T>>
A<T>(T a)
{
std::cout << "integer" << std::endl;
this->t = a;
}
A<T>(A<T> const & a)
{
this->t = a.t;
}
public:
A<T> add(A<T> & a)
{
t += a.t;
return *this;
}
friend A<T> operator + (A<T> & a1, A<T> & a2)
{
return a1.add(a2);
}
T t;
};
template<typename T1, typename T2>
struct HasPlusT
{
private:
template <typename T>
using Rr = typename std::remove_reference<T>::type;
template<typename U1, typename U2>
static auto test(void *)
-> decltype(std::declval<Rr<U1>>() + std::declval<Rr<U2>>() , '0');
template<typename...>
static long test(...);
public:
static constexpr bool value
= IsSameT<decltype(test<T1,T2>(nullptr)),char>::value;
};
template<typename T1,typename T2, bool = HasPlusT<T1,T2>::value>
struct PlusResultT
{
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
using Type = decltype(T1_t() + T2_t());
};
template<typename T1,typename T2>
struct PlusResultT<T1,T2,false>
{
using T1_t = typename std::remove_reference<T1>::type;
using T2_t = typename std::remove_reference<T2>::type;
using Type = decltype(T1_t() + T2_t());
};
int main()
{
constexpr bool value = HasPlusT<A<int>,A<int>>::value;
std::cout << value << std::endl;
return 0;
}