Skip to content

Commit

Permalink
Remove perfect forwarding in std::make_format_args calls (#326)
Browse files Browse the repository at this point in the history
  • Loading branch information
frederick-vs-ja authored Jul 16, 2024
1 parent faa388e commit 3c44148
Show file tree
Hide file tree
Showing 21 changed files with 29 additions and 56 deletions.
21 changes: 6 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ namespace impl {
Helper(const char* s, std::size_t len): s(s, len) {}
template <typename... Args>
std::string operator()(Args&&... args) const {
return std::vformat(s, std::make_format_args(std::forward<Args>(args)...));
return std::vformat(s, std::make_format_args(args...));
}
};
} // namespace impl
Expand Down Expand Up @@ -376,7 +376,7 @@ int main() {
```cpp
constexpr auto operator""_f(const char* fmt, size_t) {
return[=]<typename... T>(T&&... Args) { return std::vformat(fmt, std::make_format_args(std::forward<T>(Args)...)); };
return[=]<typename... T>(T&&... Args) { return std::vformat(fmt, std::make_format_args(Args...)); };
}
```

Expand Down Expand Up @@ -431,7 +431,7 @@ namespace impl {
Helper(const char* s, std::size_t len): s(s, len) {}
template <typename... Args>
std::string operator()(Args&&... args) const {
return std::vformat(s, std::make_format_args(std::forward<Args>(args)...));
return std::vformat(s, std::make_format_args(args...));
}
};
} // namespace impl
Expand Down Expand Up @@ -513,7 +513,7 @@ struct std::formatter<Frac>:std::formatter<char>{
}
};
void print(std::string_view fmt,auto&&...args){
std::cout << std::vformat(fmt, std::make_format_args(std::forward<decltype(args)>(args)...));
std::cout << std::vformat(fmt, std::make_format_args(args...));
}
```
Expand All @@ -532,20 +532,11 @@ void print(std::string_view fmt,auto&&...args){
```cpp
void print(std::string_view fmt,auto&&...args){
std::cout << std::vformat(fmt, std::make_format_args(std::forward<decltype(args)>(args)...));
std::cout << std::vformat(fmt, std::make_format_args(args...));
}
```

此处我们没有显示声明模板形参,所以展开时不能使用以往的模板形参做完美转发的模板实参,但是根据形参包展开的规则。例
`args...`展开成`args1,args2,args3...`,而上式展开成

```cpp
std::forward<decltype(args1)>(args1),
std::forward<decltype(args2)>(arsg2),
std::forward<decltype(args3)>(args3),...
```

这样我们对每个应用到的参数用 decltype 取他的类型再作为完美转发的模板参数。这样调用 `vformat`,返回 string,可以使用 cout 直接输出。
这样调用 `vformat`,返回 string,可以使用 cout 直接输出。

而关于自定义 `std::formatter` 特化,我们需要知道的是:想要自定义 **std::formatter** 模板特化需要提供两个函数,**parse****format**

Expand Down
4 changes: 2 additions & 2 deletions src/PDF版题目与答案/tex/questionAndAnswer02.tex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ \subsection{答案}
framesep=2mm]{c++}
constexpr auto operator""_f(const char* fmt, size_t) {
return [=]<typename... T>(T&&... Args) {
return std::vformat(fmt, std::make_format_args(std::forward<T>(Args)...));
return std::vformat(fmt, std::make_format_args(Args...));
};
}
\end{minted}
Expand Down Expand Up @@ -80,7 +80,7 @@ \subsection{解析}
Helper(const char* s, std::size_t len): s(s, len) {}
template <typename... Args>
std::string operator()(Args&&... args) const {
return std::vformat(s, std::make_format_args(std::forward<Args>(args)...));
return std::vformat(s, std::make_format_args(args...));
}
};
} // namespace impl
Expand Down
22 changes: 3 additions & 19 deletions src/PDF版题目与答案/tex/questionAndAnswer03.tex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ \subsection{标准答案}
}
};
void print(std::string_view fmt,auto&&...args){
std::cout << std::vformat(fmt, std::make_format_args(std::forward<decltype(args)>(args)...));
std::cout << std::vformat(fmt, std::make_format_args(args...));
}
\end{minted}

Expand All @@ -32,26 +32,10 @@ \subsection{解析}
framesep=2mm,
breaklines]{c++}
void print(std::string_view fmt,auto&&...args){
std::cout << std::vformat(fmt, std::make_format_args(std::forward<decltype(args)>(args)...));
std::cout << std::vformat(fmt, std::make_format_args(args...));
}
\end{minted}

由于使用了 C++20 简写函数模板,此处的完美转发就只能使用 decltype,显得有点诡异,其实很合理

展开的形式无非就是:

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm,
breaklines]{c++}
std::forward<decltype(args1)>(args1),
std::forward<decltype(args2)>(arsg2),
std::forward<decltype(args3)>(args3),...
\end{minted}

这两个格式化函数没必要再介绍,和第第二题的作用一样,很简单的调库。
这里实现策略使用了 C++20 简写函数模板。这两个格式化函数没必要再介绍,和第二题的作用一样,很简单的调库。

\clearpage
2 changes: 1 addition & 1 deletion src/群友提交/第02题/andyli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace impl {
Helper(const char* s, std::size_t len): s(s, len) {}
template <typename... Args>
std::string operator()(Args&&... args) const {
return std::vformat(s, std::make_format_args(std::forward<Args>(args)...));
return std::vformat(s, std::make_format_args(args...));
}
};
} // namespace impl
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第02题/happyd0g.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class formator {
public:
formator(const char* str):_inner_str(str) {}
auto operator () (auto&&... args) {
return std::vformat(_inner_str, std::make_format_args(std::forward<decltype(args)>(args)...));
return std::vformat(_inner_str, std::make_format_args(args...));
}
private:
const char* _inner_str;
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第02题/loser_linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct FormatterStream {

template<typename... Args>
std::string operator()(Args&&... args) {
return std::vformat(fmt_, std::make_format_args(std::forward<Args>(args)...));
return std::vformat(fmt_, std::make_format_args(args...));
}

std::string fmt_;
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第02题/mq卢瑟.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ constexpr auto operator""_f(const char* str, size_t)
{
return [=]<typename... T>(T&& ...args)
{
return std::vformat(str, std::make_format_args(std::forward<T>(args)...));
return std::vformat(str, std::make_format_args(args...));
};
}

Expand Down
4 changes: 1 addition & 3 deletions src/群友提交/第02题/子魂.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

constexpr auto operator ""_f(const char* s, size_t l)
{
//return [s](auto&& ...vars){ return std::vformat(s, std::make_format_args(vars...)); };
//改用完美转发
return [s](auto&& ...vars){ return std::vformat(s, std::make_format_args(std::forward<decltype(vars)>(vars)...)); };
return [s](auto&& ...vars){ return std::vformat(s, std::make_format_args(vars...)); };
}

int main()
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第02题/心洗.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ auto operator ""_f(const char* text, size_t)
auto operator ""_f(const char* text, size_t)
{
return [text](auto&&... args) {
return std::vformat(text, std::make_format_args(std::forward<decltype(args)>(args)...));
return std::vformat(text, std::make_format_args(args...));
};
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第02题/涼風青葉.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct Formatter {

template<typename ...Args>
std::string operator()(Args &&...args) const {
return std::vformat(fmt, std::make_format_args(std::forward<Args>(args)...));
return std::vformat(fmt, std::make_format_args(args...));
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/CodeyZ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct std::formatter<Frac, char> {

template<typename...Args>
auto print(std::string_view s,Args&&...args) {
std::cout << std::vformat(s,std::make_format_args(std::forward<Args>(args)...)) << '\n';
std::cout << std::vformat(s,std::make_format_args(args...)) << '\n';
}

int main() {
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/SocialMean.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct std::formatter<Frac, charT> : std::formatter<int, charT> {
template <typename... Args>
void print(const char* fmt, Args&&... args) {
std::cout << std::vformat(fmt,
std::make_format_args(std::forward<Args>(args)...))
std::make_format_args(args...))
<< '\n';
}

Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/happyd0g.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct std::formatter<Frac> : std::formatter<int> {
};

void print(const char* str, auto&& ... args) {
std::cout << std::vformat(str, std::make_format_args(std::forward<decltype(args)>(args)...));
std::cout << std::vformat(str, std::make_format_args(args...));
}

int main()
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/jacky.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct std::formatter<Frac, CharT> : std::formatter<int, CharT> {

constexpr void print(const char* fmt, auto&&... args)
{
std::fputs(std::vformat(fmt, std::make_format_args(std::forward<decltype(args)>(args)...)).c_str(), stdout);
std::fputs(std::vformat(fmt, std::make_format_args(args...)).c_str(), stdout);
}

int main()
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/joe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct std::formatter<Frac, CharT> : std::formatter<int, CharT>

void print(const char* fmt, auto&& ...frac)
{
std::cout<< std::vformat(fmt,std::make_format_args(std::forward<decltype(frac)>(frac)...));
std::cout<< std::vformat(fmt,std::make_format_args(frac...));
}

int main()
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/loser_linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct std::formatter<Frac, CharT> : std::formatter<int, CharT>

template<typename... Args>
void print(char const * str, Args&&... args){
std::cout << std::vformat(str,std::make_format_args(std::forward<Args>(args)...));
std::cout << std::vformat(str,std::make_format_args(args...));
}

int main()
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/mq卢瑟.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ struct Frac {

template<typename... Args>
void print(std::string_view format_str, Args const&... args) {
std::cout << std::vformat(format_str, std::make_format_args(std::forward<decltype(args)>(args)...));
std::cout << std::vformat(format_str, std::make_format_args(args...));
}

template<>
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/mq日.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ template<> struct std::formatter<Frac> : std::formatter<int>

void print(const char *str, auto &&...args)
{
std::cout << std::vformat(str, std::make_format_args(std::forward<decltype(args)>(args)...));
std::cout << std::vformat(str, std::make_format_args(args...));
}

int main()
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/子魂.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

void print(const char* s, auto&&... vars)
{
std::cout << std::vformat(s, std::make_format_args(std::forward<decltype(vars)>(vars)...));
std::cout << std::vformat(s, std::make_format_args(vars...));
}

struct Frac
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/心洗.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void print(auto&& text, auto&&... args)
{
std::cout << std::vformat(
std::forward<decltype(text)>(text),
std::make_format_args(std::forward<decltype(args)>(args)...));
std::make_format_args(args...));
}

int main()
Expand Down
2 changes: 1 addition & 1 deletion src/群友提交/第03题/涼風青葉.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct std::formatter<Frac> : std::formatter<char> {

template<typename T, typename ...Args>
void print(const T &fmt, Args &&...args) {
std::cout << std::vformat(fmt, std::make_format_args(std::forward<Args>(args)...));
std::cout << std::vformat(fmt, std::make_format_args(args...));
}

int main() {
Expand Down

0 comments on commit 3c44148

Please sign in to comment.