c++ 如何理解`T(*(T,std::_Placeholder< 2>))(T,T)`这样的类型?

wz1wpwve  于 2023-03-25  发布在  其他
关注(0)|答案(2)|浏览(168)

一个简单的代码片段

#include <cstdio>
#include <functional>

int main() {
    auto f = std::bind(printf, "%d", std::placeholders::_2);
}

转变为

#include <cstdio>
#include <functional>

int main()
{
  std::_Bind<int (*(const char *, std::_Placeholder<2>))(const char *, ...)> f = std::bind(printf, "%d", std::placeholders::_2);
  return 0;
}

使用cppinsights.io.(参见https://cppinsights.io/s/71938cf6
如何理解返回类型std::_Bind<int (*(const char *, std::_Placeholder<2>))(const char *, ...)>int (*(const char *, std::_Placeholder<2>))(const char *, ...)部分?
我知道int (*)(const char *, ...)是一个函数指针类型,但是(*(const char *, std::_Placeholder<2>))的含义是什么?有什么链接可以进一步理解这个类型吗?
编辑:我的坏为一个误导性的标题。我想问的是,如何理解类型int (*(const char *, std::_Placeholder<2>))(const char *, ...),以及如何命名这种类型。std::bind只是这个问题的介绍,它给了我一个奇怪的类型,我从来没有见过。

sqyvllje

sqyvllje1#

实际上没有必要理解std::bind返回的类型。
也就是说,我们不能像问题中那样将模板类型的不同部分分开,它们都是 * 单个 * 类型的一部分,只能作为一个整体使用。它基本上归结为一个函数返回指向另一个函数的指针,而另一个函数(实际上是printf)返回int
如果我们使用类型别名,可能会更容易:

using printf_function_type = int(const char *, ...);

using wrapped_function_type = printf_function_type*(const char *, std::_Placeholder<2>);

using bind_type = std::_Bind<wrapped_function_type>;

第一个别名用于printf函数。
第二个别名是一个函数,它接受一个const char *和一个“占位符”对象作为参数,并返回一个指向printf类型函数的指针。
第三个别名是使用函数的可调用对象的内部编译器特定类型。
std::bind调用返回的是bind_type类型的值。

cyvaqqii

cyvaqqii2#

并不是说我在不知道解决方案的情况下发现了这一点,但我最近发现了这样一种方法来表达一些函数(和函数指针)类型:

#include <cstdio>
#include <functional>

int main() {
  
std::_Bind<int (*(const char *, std::_Placeholder<2>))(const char *, ...)> f = std::bind(printf, "%d", std::placeholders::_2);  return 0;

using T = std::_Bind< int (*(const char *, std::_Placeholder<2>))(const char *, ...)               >;

using U = std::_Bind< auto(const char *, std::_Placeholder<2>) ->  auto(*)(const char *, ...)->int >;

static_assert( std::is_same<T, U>::value );
}

https://godbolt.org/z/qbjfMEMf7
从左到右阅读,“它是一个具有char*Placeholder输入的函数,它输出一个具有char*(和变元)输入和整数输出的函数 * 指针 *”。
注意,括号不能用于类型声明(如表达式),所以我使用了额外的空格来明确结合性。
(另外使用east-const也会有所帮助。)

相关问题