惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
SegmentFault 最新的问题
Y
Y Combinator Blog
Recorded Future
Recorded Future
博客园 - Franky
I
InfoQ
T
The Blog of Author Tim Ferriss
Recent Announcements
Recent Announcements
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
Cyberwarzone
Cyberwarzone
The Register - Security
The Register - Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
雷峰网
雷峰网
P
Palo Alto Networks Blog
G
GRAHAM CLULEY
Cloudbric
Cloudbric
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
F
Full Disclosure
Google DeepMind News
Google DeepMind News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Check Point Blog
爱范儿
爱范儿
The GitHub Blog
The GitHub Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
U
Unit 42
N
Netflix TechBlog - Medium
The Cloudflare Blog
Spread Privacy
Spread Privacy
Microsoft Azure Blog
Microsoft Azure Blog
美团技术团队
T
Troy Hunt's Blog
Engineering at Meta
Engineering at Meta
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tenable Blog
B
Blog
S
Securelist
H
Hacker News: Front Page
Google Online Security Blog
Google Online Security Blog
G
Google Developers Blog

Jia Yue Hua

完美转发不完美 闲散颂 adapting c++20 ranges algorithms for most metaprogramming Reproducible github Developer Environments 使用mpmcpipeline和jthread实现软流水 在其它线程周期回调函数 在当前线程周期回调函数 for_each transparent,为关联容器增加查找成员
cpo和tag_invoke
Jia Yue Hua · 2023-05-18 · via Jia Yue Hua

customization point object(cpo)和tag_invoke由eric niebler提出,在ranges和executor中有很多应用。 cpo可用于对库中的一些仿函数进行定制,而tag_invoke用于实现cpo,用于用户的类区分对于不同库的定制。

#include <gtest/gtest.h>
#include <folly/Utility.h>
#include <folly/lang/CustomizationPoint.h>
#include <folly/functional/Invoke.h>
template<class T>
struct Tag {
};

template<class T>
constexpr auto tag_c = Tag<T>{};
namespace A
{
struct FooCpo {
 template<typename T>
 auto operator()(Tag<T> t) const
     noexcept(folly::is_nothrow_tag_invocable_v<FooCpo, Tag<T> >)
     -> folly::tag_invoke_result_t<FooCpo, Tag<T>> {
   return folly::tag_invoke(*this, t);
 }
};
struct BarCpo {
     template<typename A>
     auto operator()(A&&a ) const
         noexcept(folly::is_nothrow_tag_invocable_v<BarCpo, A>)
         -> folly::tag_invoke_result_t<BarCpo, A> {
       return folly::tag_invoke(*this, (A&&)a);
     }
};
FOLLY_DEFINE_CPO(BarCpo, doathing)
FOLLY_DEFINE_CPO(FooCpo, dosomething)
}

namespace B
{
struct FooCpo {
 template<typename A>
 auto operator()(Tag<A> t) const
     noexcept(folly::is_nothrow_tag_invocable_v<FooCpo, Tag<A> >)
     -> folly::tag_invoke_result_t<FooCpo, Tag<A>> {
   return folly::tag_invoke(*this, t);
 }
};
FOLLY_DEFINE_CPO(FooCpo, dosomething)
}
namespace My
{
class SomeClass
{
  friend void tag_invoke(folly::cpo_t<A::dosomething>, Tag<SomeClass>)
  { std::cout << "A someclass\n";
  }
  friend void tag_invoke(folly::cpo_t<A::doathing>, const  SomeClass& some)
  { std::cout << "A doathing someclass\n";
  }
  friend void tag_invoke(folly::cpo_t<B::dosomething>, Tag<SomeClass>)
  { std::cout << "B someclass\n";
  }
};

}

TEST(cpo, basic)
{
  My::SomeClass c;
  A::doathing(c);
}
TEST(cpo, advance)
{
  A::dosomething(tag_c<My::SomeClass>);
  B::dosomething(tag_c<My::SomeClass>);
}

上文的 BarCpo 示范了如何定义一个cpo, BarCpo有一个模板成员operator(),内部调用tag_invoke, FOLLY_DEFINE_CPO(BarCpo, doathing) 帮我们定义了BarCpo类型的doathing cpo.

类My::SomeClass friend void tag_invoke(folly::cpo_t<A::doathing>, const SomeClass& some)实现了对A::doathing的定制。TEST(cpo,basic)中的A:::doathing(c)调用了我们实现的定制。

My::SomeClass 的友元void tag_invoke(folly::cpo_t<A::dosomething>, Tag)和 friend void tag_invoke(folly::cpo_t<B::dosomething>, Tag) 示范了对于不同名字空间A和B的dosomthing cpo,tag_invoke可方便的分别定制.