我希望在没有将小于(<)运算符定义的类型传递给'myclass'时抛出异常。我添加了一些示例代码来帮助解释我想要做的事情。
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;
}
未来观众的注意事项:Nacl对问题的回答解决了问题,Columbo提供了更优雅的解决方案。
答案 0 :(得分:4)
如果在编译时可以static_assert
,为什么要抛出异常?
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>;
使用示例:
static_assert( LessThanComparable<std::string>::value, "" );
static_assert( LessThanComparable<int>::value, "" );
static_assert( !LessThanComparable<std::ostream>::value, "" );
Demo。与模板参数等效的工作:
template <typename T>
struct MyTemplate
{
static_assert( LessThanComparable<T>::value,
"Invalid type - must have less-than operator implemented" );
};
答案 1 :(得分:1)
这没用。实际上没有用于检查异常的用例,因为它们在运行时抛出,模板在编译时工作。使用Columbo提到的static_assert
。
但你可以这样做:
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>;
为了使用它,你可以
try
{
CLASS<Foo> c;
}
catch(std::exception& e)
{
std::cout << e.what();
}