gpt4 book ai didi

c++ - 是否有一些技巧可以让我将流操纵器传递给可变参数模板函数?

转载 作者:可可西里 更新时间:2023-11-01 15:37:38 25 4
gpt4 key购买 nike

我一直在尝试为 std::cout 编写一个线程安全的包装器,我认为现在是学习可变参数模板的好时机。

Like that.

然后,就在我认为我做对了的时候,我注意到它不适用于 std::endl。

拿这段代码:

template <typename... P>
void f(P...){}

int main()
{
f(1,2,3,std::endl);
}

当您尝试编译它时,GCC 以一种非常愚蠢的方式提示:

main.cpp:18:19: error: too many arguments to function 'void f(P ...) [with P = {}]'

当您尝试使用常规模板时,您会得到

main.cpp:22:13: error: no matching function for call to 'f(<unresolved overloaded function type>)'

这实际上是有道理的。

这对我来说不是什么大问题,我可以通过其他方式做到这一点,但我真的很想知道是否有办法绕过这个限制。

最佳答案

我推荐模板参数推导,而不是 Andy Prowl 建议的显式模板参数:

C:\Temp>type meow.cpp
#include <iostream>
#include <utility>
using namespace std;

void Print() { }

template <typename T, typename... Rest> void Print(T&& t, Rest&&... rest) {
cout << forward<T>(t);
Print(forward<Rest>(rest)...);
}

int main() {
ostream& (* const narrow_endl)(ostream&) = endl;

Print("Hello, world!", narrow_endl, "I have ", 1729, " cute fluffy kittens.",
static_cast<ostream& (*)(ostream&)>(endl)
);
}

C:\Temp>cl /EHsc /nologo /W4 /MTd meow.cpp
meow.cpp

C:\Temp>meow
Hello, world!
I have 1729 cute fluffy kittens.

N3690 13.4 [over.over] 指定此处使用的规则,可追溯到 C++98。基本上,获取重载和/或模板化函数的地址通常是不明确的,但在特定上下文中是允许的。 Initialization 和 static_casting 是其中的两个上下文,因为它们提供了足够的类型信息来消除歧义。这允许模板参数推导正常进行。

显式模板参数非常诱人,但它们会以各种方式爆炸。 std::endl 不太可能会以破坏此处显式模板参数的方式进行更改,但我真的建议不要这样做(除非是专门为它们设计的,例如 forward 和 make_shared)。

关于c++ - 是否有一些技巧可以让我将流操纵器传递给可变参数模板函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17119044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com