C++ 确保c++;类具有某些成员函数

C++ 确保c++;类具有某些成员函数,c++,templates,types,C++,Templates,Types,重复: 我正在实现一个模板类,我想确保模板是由一个类实例化的,该类具有操作符C++模板的类似行为。如果它看起来像鸭子,走路像鸭子,嘎嘎叫像鸭子,那么它就是鸭子。基本上,如果您在模板参数的实例中使用运算符或调用函数,则需要使用该参数来重写该运算符或实现该方法。如已经说过的,如果C++模板类使用模板参数的任何函数或成员,则已经使用了< < /p> 编译器将在编译期间检查实例化类型是否具有这些函数和成员 如果需要显式检查,可以使用此库指定实例化类型需要满足的约束 检查概念类的示例: template

重复:


我正在实现一个模板类,我想确保模板是由一个类实例化的,该类具有操作符C++模板的类似行为。如果它看起来像鸭子,走路像鸭子,嘎嘎叫像鸭子,那么它就是鸭子。基本上,如果您在模板参数的实例中使用运算符或调用函数,则需要使用该参数来重写该运算符或实现该方法。如已经说过的,如果C++模板类使用模板参数的任何函数或成员,则已经使用了< < /p> 编译器将在编译期间检查实例化类型是否具有这些函数和成员

如果需要显式检查,可以使用此库指定实例化类型需要满足的约束

检查概念类的示例:

template <class X>
struct InputIterator
  : Assignable<X>, EqualityComparable<X>
{
 private:
    typedef std::iterator_traits<X> t;
 public:
    typedef typename t::value_type value_type;
    typedef typename t::difference_type difference_type;
    typedef typename t::reference reference;
    typedef typename t::pointer pointer;
    typedef typename t::iterator_category iterator_category;

    BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
    BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));

    BOOST_CONCEPT_USAGE(InputIterator)
    {
        X j(i);             // require copy construction
        same_type(*i++,v);  // require postincrement-dereference returning value_type
        X& x = ++j;         // require preincrement returning X&
    }

 private:
    X i;
    value_type v;

    // Type deduction will fail unless the arguments have the same type.
    template <typename T>
    void same_type(T const&, T const&);
};
模板
结构输入计算器
:可分配的,相等的
{
私人:
typedef std::迭代器;
公众:
typedef typename t::value_type value_type;
typedef typename t::difference_type difference_type;
typedef typename t::reference引用;
typedef typename t::指针指针;
typedef typename t::迭代器\类别迭代器\类别;
BOOST_CONCEPT_ASSERT((SignedInteger));
BOOST_CONCEPT_ASSERT((可转换));
增强概念使用(输入计算器)
{
xj(i);//需要复制构造
相同的_类型(*i++,v);//要求增量后取消引用返回值_类型
X&X=++j;//要求预增量返回X&
}
私人:
xi;
v型值;
//除非参数具有相同的类型,否则类型推断将失败。
模板
无效同一类型(T常数和,T常数和);
};
使用该概念的示例:

// In my library:
template <class It>
class generic_library_class
{
  BOOST_CONCEPT_ASSERT((InputIterator<It>));
  // ...
};

// In the user's code:  
class foo {
  //... 
};

int main() {
  generic_library_class<std::vector<char>::iterator> y;
  //... 
}
//在我的库中:
模板
类泛型\u库\u类
{
BOOST_CONCEPT_ASSERT((输入计算器));
// ...
};
//在用户代码中:
福班{
//... 
};
int main(){
通用_库_y类;
//... 
}

C++11提供了一个非常方便的运算符,它允许查询表达式的结果类型,而该表达式在运行时根本不进行计算,只在编译时进行计算

这与
一起,可用于手工编写
静态断言的模板帮助程序:

#include <type_traits>

template <typename T, typename = void>
struct is_equality_comparable : std::false_type {};

template <typename T>
struct is_equality_comparable<T,
        typename std::enable_if<
          std::is_convertible<decltype(std::declval<T&>() == std::declval<T&>())
          , bool>{}>::type
        > : std::true_type {};

template <typename T, typename = void>
struct is_less_than_comparable : std::false_type {};

template <typename T>
struct is_less_than_comparable<T,
        typename std::enable_if<
          std::is_convertible<decltype(std::declval<T&>() < std::declval<T&>())
          , bool>{}>::type
        > : std::true_type {};
现在,让我们将约束应用于类:

// your template classes with constraints:

template <typename T>
class MustBeEqComparable
{
    static_assert(is_equality_comparable<T>::value,
                  "Type T is not equality comparable!");
};

template <typename T>
class MustBeLessThanComparable
{
    static_assert(is_less_than_comparable<T>::value,
                  "Type T is not less than comparable!");
};
//具有约束的模板类:
模板
类必须是可比较的
{
静态断言(是否相等?是否可比较::值,
“T型不可比!”;
};
模板
类必须具有可比性
{
静态断言(小于可比::值,
“T型不低于可比水平!”);
};
现在,让我们尝试实例化每个:

MustBeEqComparable<EqComparable> a;

MustBeEqComparable<NotComparableAtAll> b; // issues an error

MustBeLessThanComparable<LessThanComparable> c;

MustBeLessThanComparable<NotComparableAtAll> d; // issues an error
必须是可比较的;
必须是可比较的b;//发出错误
必须低于c;
必须小于或等于d;//发出错误

运算符重载?假设是这样?如果没有,那么你会得到编译器错误。纯虚拟操作符?这是一个复制品吗?没有C++没有使用鸭子打字。我想我的意思是C++模板像鸭子打字一样功能。模板最可靠的是鸭子类型。@你是QuasasbRube?还是有技术上的区别?如果是,请澄清。
MustBeEqComparable<EqComparable> a;

MustBeEqComparable<NotComparableAtAll> b; // issues an error

MustBeLessThanComparable<LessThanComparable> c;

MustBeLessThanComparable<NotComparableAtAll> d; // issues an error