Читая главу 22 шаблонов C ++, второе издание, я пытаюсь понять реализацию черты EqualityComparable.Но я не могу понять, как компилятор решил активировать запасной вариант или нет.
В дополнение к этому есть две функции, которые только объявлены, но программа компилируется и запускается.Это странно для меня.
Вот код.Заголовочный файл IsEqualityComparable.hpp
#include <utility> // for declval()
#include <type_traits> // for true_type and false_type
template<typename T>
class IsEqualityComparable
{
private:
// test convertibility of == and ! == to bool:
static void* conv(bool); // to check convertibility to bool
template<typename U>
static std::true_type test(decltype(conv(std::declval<U const&>() ==
std::declval<U const&>())),
decltype(conv(!(std::declval<U const&>() ==
std::declval<U const&>())))
);
// fallback:
template<typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(nullptr,
nullptr))::value;
};
Исходным файлом является следующий
#include <iostream>
#include <exception>
#include <utility>
#include <functional>
#include "isequalitycomparable.hpp"
template<typename T,
bool EqComparable = IsEqualityComparable<T>::value>
struct TryEquals
{
static bool equals(T const& x1, T const& x2) {
std:: cout << "IsEqualityComparable equals::"<<std::endl;
return x1 == x2;
}
};
class NotEqualityComparable : public std::exception
{
};
template<typename T>
struct TryEquals<T, false>
{
static bool equals(T const& x1, T const& x2) {
std:: cout << "Throw::"<<std::endl;
throw NotEqualityComparable();
}
};
void foo(int)
{
}
void bar(int)
{
}
class A
{
public:
A() = default;
friend bool operator ==(A a1 , A a2)
{
return true;
}
};
int main()
{
std:: cout << "Enter" << std::endl;
std::function<void(int)> f = foo;
std::function<void(int)> f2 = f;
std:: cout << "Enter" << std::endl;
//std:: cout << "Check::"<<
//TryEquals<std::function<void(int)>>::equals(f,f2) << std::endl;
A a1;
A a2;
std:: cout << "Check::"<< TryEquals<A>::equals(a1,a2) << std::endl;
return 0;
}
TryEquals<std::function<void(int)>>::equals(f,f2)
вызывает исключение, посколькуоператор == не реализован, но
TryEquals<A>::equals(a1,a2)
возвращает 1, поскольку в классе A есть оператор ==.
В этом пункте мне нужна помощь, чтобы понять, как conv и test работают.
Кроме того, как работает
static constexpr bool value = decltype(test<T>(nullptr,
nullptr))::value
?
Я перепутал это выражение
decltype(test<T>(nullptr,nullptr))::value.