Reputation: 19
I want to throw an exception when a type that does not have the less than (<) operator defined is passed into 'myclass'. I added in some sample code to help explain what I want to do.
template<typename T>
class CLASS {
public:
CLASS()
{
//if('T' does not have '<' operator defined)
//{
// throw exception;
//}
}
private:
T mProperty;
};
class PlainClass {
public:
PlainClass() {}
private:
int num = 0;
};
int main()
{
CLASS<int> ok; //ok
CLASS<PlainClass> error; //throws exception
return 0;
}
Note for future viewers: Nacl's answer to the question resolves the problem and Columbo provides a more elegant solution.
Upvotes: 0
Views: 203
Reputation: 2723
It's very useless. There is really no usecase to check this with exceptions as they are thrown at run time and templates work at compile time. Use static_assert
as mentioned by Columbo.
But you can do it for example like this:
namespace somenamespace
{
typedef char no[7];
template<typename T> no& operator<(const T&, const T&);
template<typename T>
struct checker
{
enum { value = (sizeof(*(T*)(0) < *(T*)(0)) != sizeof(no)) };
};
}
template<typename T, bool>
struct CLASS_helper
{
CLASS_helper(){/*some cool constructor*/}
};
template<typename T>
struct CLASS_helper<T, false>
{
CLASS_helper()
{
std::string str("No operator< specified for ");
str += typeid(T).name();
str += ".\n";
throw std::logic_error(str);
};
};
template<typename T>
using CLASS = CLASS_helper<T, somenamespace::checker<T>::value>;
In order to use this you do
try
{
CLASS<Foo> c;
}
catch(std::exception& e)
{
std::cout << e.what();
}
Upvotes: 1
Reputation: 61009
Why throw an exception if you can static_assert
at compile time?
template <typename T, typename=void>
struct LessThanComparable_ : std::false_type {};
template <typename T>
struct LessThanComparable_<T,
decltype(void(std::declval<T>() < std::declval<T>()))>
: std::true_type {};
template <typename T>
using LessThanComparable = LessThanComparable_<T>;
Example usage:
static_assert( LessThanComparable<std::string>::value, "" );
static_assert( LessThanComparable<int>::value, "" );
static_assert( !LessThanComparable<std::ostream>::value, "" );
Demo. Works equivalent with template parameters:
template <typename T>
struct MyTemplate
{
static_assert( LessThanComparable<T>::value,
"Invalid type - must have less-than operator implemented" );
};
Upvotes: 4