c++(2):std::equal_to、std::result_of、 std::invoke_result、std::is_convertible、is_nothrow_convertible

1 std::equal_to

1.1 定义

        在头文件<functional>

        下面先定义一个模板类class T,然后定义一个结构体equal_to

template< class T >
struct equal_to;
		(until C++14)
template< class T = void >
struct equal_to;
		(since C++14)

1.2 功能

        原文为:

Function object for performing comparisons. Unless specialised, invokes operator== on type T.

        这里理解为比较两个成员参数的类型是否一致,一致时返回bool类型的true,否则返回bool类型的false

1.3 成员类型

TypeDefinition
result_type (deprecated in C++17)(removed in C++20)--返回值bool
first_argument_type (deprecated in C++17)(removed in C++20)--第一个参数T
second_argument_type (deprecated in C++17)(removed in C++20)--第二个参数T

1.4 成员函数operator()

        成员函数全称为 std::equal_to::operator();下面代码应该在equal_to这个结构体里面定义的,所以没加前面的std::equal_to::

//使用方式
bool operator()( const T& lhs, const T& rhs ) const;
		(until C++14)
constexpr bool operator()( const T& lhs, const T& rhs ) const;
		(since C++14)

        用于比较lhs和 rhs是否一致;一致返回true,否则为false

        一种定义/实现方法:

constexpr bool operator()(const T &lhs, const T &rhs) const 
{
    return lhs == rhs;
}

官方链接:std::equal_to - cppreference.com

2 std::result_of, std::invoke_result

        std::result_of和std::invoke_result功能类似,这里一起介绍.

        功能:在编译时推导出表达式的返回类型----我暂时是这样理解的

2.1 定义

        定义在头文件<type_traits>

//这个应该是result_of最初版本的定义,没有进行详细定义
template< class >
class result_of; // not defined
//(since C++11)

// result_of的定义,定义了模板类F,参数ArgTypes--可以有多个,以及result_of
template< class F, class... ArgTypes >
class result_of<F(ArgTypes...)>;
//(deprecated in C++17)
//(removed in C++20)

// 和上面类似
template< class F, class... ArgTypes>
class invoke_result;
//(since C++17)

2.2 参数

        F 必须是可调用类型、对函数的引用或对可调用类型的引用。 使用 ArgTypes... 调用 F必须是格式良好的表达式。
        F 和 ArgTypes 中的所有类型可以是任何完整类型、未知边界数组或(可能是 cv 限定的)void。

2.3 扩展类型(helper types)

        result_of_t、invoke_result_t

template< class T >
using result_of_t = typename result_of<T>::type;
	(1)(since C++14)
    (deprecated in C++17)
    (removed in C++20)

template< class F, class... ArgTypes>
using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
	(2)(since C++17)

2.4 示例代码及在线运行

        (注:编译要求的c++版本较高)

        示例代码命名为main.cpp,内容如下:

#include <type_traits>
#include <iostream>
 
struct S {
    double operator()(char, int&);
    float operator()(int) { return 1.0;}
};
 
template<class T>
typename std::result_of<T(int)>::type f(T& t)
{
    std::cout << "overload of f for callable T\n";
    return t(0);
}
 
template<class T, class U>
int f(U u)
{
    std::cout << "overload of f for non-callable T\n";
    return u;
}
 
int main()
{
    // the result of invoking S with char and int& arguments is double
    std::result_of<S(char, int&)>::type d = 3.14; // d has type double
    static_assert(std::is_same<decltype(d), double>::value, "");
 
    // std::invoke_result uses different syntax (no parentheses)
    std::invoke_result<S,char,int&>::type b = 3.14;
    static_assert(std::is_same<decltype(b), double>::value, "");
 
    // the result of invoking S with int argument is float
    std::result_of<S(int)>::type x = 3.14; // x has type float
    static_assert(std::is_same<decltype(x), float>::value, "");
 
    // result_of can be used with a pointer to member function as follows
    struct C { double Func(char, int&); };
    std::result_of<decltype(&C::Func)(C, char, int&)>::type g = 3.14;
    static_assert(std::is_same<decltype(g), double>::value, "");
 
    f<C>(1); // may fail to compile in C++11; calls the non-callable overload in C++14
}

        编译运行命令:

g++ main.cpp && ./a.out

        运行结果:

overload of f for non-callable T

        在线运行网站如下,也可以找国内的网站:

Coliru

3 std::is_convertible, std::is_nothrow_convertible

        功能:判断两个类型能否相互转化

3.1 定义

        注意两者在不同c++版本中的使用

template< class From, class To >
struct is_convertible;
	(1) 	(since C++11)
template< class From, class To >
struct is_nothrow_convertible;
	(2) 	(since C++20)

        拓展类型定义:

template< class From, class To >
inline constexpr bool is_convertible_v = is_convertible<From, To>::value;
		(since C++17)
template< class From, class To >
inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value;
		(since C++20)

3.2 返回值

        如果 From 可转换为 To 则为 true ,否则为 false

3.3 示例代码

(注:本地运行的话注意c++版本,建议在线运行)

#include <iomanip>
#include <iostream>
#include <string>
#include <string_view>
#include <type_traits>
 
class E { public: template<class T> E(T&&) { } };
 
int main()
{
    class A {};
    class B : public A {};
    class C {};
    class D { public: operator C() { return c; }  C c; };
 
    std::cout
        << std::boolalpha
        << std::is_convertible_v<B*, A*> << ' '  // true
        << std::is_convertible_v<A*, B*> << ' '  // false
        << std::is_convertible_v<D, C> << ' '    // true
        << std::is_convertible_v<B*, C*> << ' '  // false
        // Note that the Perfect Forwarding constructor makes the class E be
        // "convertible" from everything. So, A is replaceable by B, C, D..:
        << std::is_convertible_v<A, E> << ' ';   // true
 
    using std::operator "" s, std::operator "" sv;
 
    auto stringify = []<typename T>(T x) {
        if constexpr (std::is_convertible_v<T, std::string> or
                      std::is_convertible_v<T, std::string_view>) {
            return x;
        } else {
            return std::to_string(x);
        }
    };
 
    const char* three = "three";
 
    std::cout
        << std::is_convertible_v<std::string_view, std::string> << ' ' // false
        << std::is_convertible_v<std::string, std::string_view> << ' ' // true
        << std::quoted(stringify("one"s)) << ' '
        << std::quoted(stringify("two"sv)) << ' '
        << std::quoted(stringify(three)) << ' '
        << std::quoted(stringify(42)) << ' '
        << std::quoted(stringify(42.)) << '\n';
}

        编译命令

g++ main.cpp && ./a.out

@meng

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值