Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何检查是否为C+;中的模板定义了特定运算符+;?_C++_Templates_Sfinae - Fatal编程技术网

C++ 如何检查是否为C+;中的模板定义了特定运算符+;?

C++ 如何检查是否为C+;中的模板定义了特定运算符+;?,c++,templates,sfinae,C++,Templates,Sfinae,当一个类型没有小于(的属性时,我想抛出一个异常,如果您可以在编译时static\u assert,为什么要抛出一个异常 template <typename T, typename=void> struct LessThanComparable_ : std::false_type {}; template <typename T> struct LessThanComparable_<T, decltype(void(std::declval<T>

当一个类型没有小于(的属性时,我想抛出一个异常,如果您可以在编译时
static\u 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>;
模板
struct lessthan可比类型{:std::false{};
模板
结构lessthan_
:std::true_type{};
模板
使用Lessthan Comparable=Lessthan Comparable\ux;
用法示例:

static_assert( LessThanComparable<std::string>::value, "" );
static_assert( LessThanComparable<int>::value, "" );
static_assert( !LessThanComparable<std::ostream>::value, "" );
static_断言(LessThanComparable::value,”);
静态_断言(LessThanComparable::value,“”);
静态断言(!LessThanComparable::value,“”);
.与模板参数等效的工程:

template <typename T>
struct MyTemplate
{
    static_assert( LessThanComparable<T>::value,
                   "Invalid type - must have less-than operator implemented" );
};
模板
结构MyTemplate
{
静态断言(小于可比::值,
“无效类型-必须实现少于个运算符”);
};

如果可以在编译时
static\u 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>;
模板
struct lessthan可比类型{:std::false{};
模板
结构lessthan_
:std::true_type{};
模板
使用Lessthan Comparable=Lessthan Comparable\ux;
用法示例:

static_assert( LessThanComparable<std::string>::value, "" );
static_assert( LessThanComparable<int>::value, "" );
static_assert( !LessThanComparable<std::ostream>::value, "" );
static_断言(LessThanComparable::value,”);
静态_断言(LessThanComparable::value,“”);
静态断言(!LessThanComparable::value,“”);
.与模板参数等效的工程:

template <typename T>
struct MyTemplate
{
    static_assert( LessThanComparable<T>::value,
                   "Invalid type - must have less-than operator implemented" );
};
模板
结构MyTemplate
{
静态断言(小于可比::值,
“无效类型-必须实现少于个运算符”);
};

这是非常无用的。用异常检查这一点确实没有用,因为它们在运行时抛出,而模板在编译时工作。使用Columbo提到的
静态断言

但您可以这样做,例如:

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>;
名称空间
{
typedef字符编号[7];

模板no&operator这是非常无用的。检查异常是没有用的,因为它们在运行时抛出,模板在编译时工作。使用Columbo提到的
static\u 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>;
名称空间
{
typedef字符编号[7];


模板否&运算符为什么异常?模板是编译时的,编译器错误不是更好吗?我认为这是不可能的。如果没有有效的运算符,编译器不会让它编译。我被告知,如果我想在赋值中获得额外分数,我需要抛出异常…所以我假设它会在这里,但我想我是wrong.谢谢您的输入。@PlaydohLegs,如果您尝试执行的任何操作都接收到无效值,而不是无效类型,则听起来您应该引发异常。例如,如果您有一个赋值来确定列表中最低的元素,则如果列表为空,您可能会引发异常,即使列表的项类型不支持ort the
@hvd谢谢你的建议,我将把它合并到我的应用程序中。为什么异常?模板是编译时的,编译器错误不是更好吗?我不认为这是可能的。如果没有有效的运算符,编译器不会让它编译。我被告知,如果我想在赋值上获得额外的分数,我需要抛出异常…所以我假设它会在这里,但我猜我错了。谢谢您的输入。@PlaydohLegs,如果您尝试执行的任何操作接收到无效值,而不是无效类型,则听起来您应该引发异常。例如,如果您有一个赋值来确定列表中最低的元素,您可能会引发异常如果列表是空的,即使列表的项类型确实支持
@hvd谢谢你的建议,我也会将其合并到我的应用程序中。为什么还要断言呢?如果你试图编译,而类没有
@Cyber,OP的目的不是要有某种正确的错误消息吗?是的,但是编译器错误可能会说明一些问题g像
错误没有匹配的函数来调用…
并直接指向有问题的行。没有比这更清楚的了。@Cyber你在开玩笑吗?编译器可能会尝试匹配
运算符的双精度,为什么还要断言呢?如果你试图编译,而类没有
。@Cyber不是OP想要有某种属性的意图r错误消息?是的,但编译器错误可能会说类似于
error no matching function for call to…
,并直接指向有问题的行。没有比这更清楚的了。@Cyber你在开玩笑吗?编译器可能会尝试匹配
operatorNice的douzens,这直接回答了我的问题。很好,这回答了我的问题直接提问。