gpt4 book ai didi

c++ - VS2013 上的模板特化和 SFINAE

转载 作者:行者123 更新时间:2023-11-30 02:40:43 25 4
gpt4 key购买 nike

我正在使用 VS2013(更新 4),但在编译以下可变参数模板代码时遇到了问题:

#include <iostream>
#include <string>

// Variadic template "multiwrite" for writing a string to multiple different streams
template <typename T>
void mwrite(T value, std::ostream& os) { os << value; }
template <typename T, typename... SS>
void mwrite(T value, std::ostream& os, SS... streams) { mwrite(value, os); mwrite(value, streams...); }

// Main
int main()
{
std::ostream& out = std::cout;
std::ostream& err = std::cerr;
mwrite(std::string("Hello"), out, err);
return 0;
}

我得到的编译器错误是:

error C2280: 'std::basic_ostream<char,std::char_traits<char>>::basic_ostream(const std::basic_ostream<char,std::char_traits<char>> &)' : attempting to reference a deleted function
see declaration of 'std::basic_ostream<char,std::char_traits<char>>::basic_ostream'

我已经尝试使用 std::ostreams 以外的其他类型来实现此功能,并且它们工作正常。此外,我知道 ostream 没有复制构造函数这一事实,起初我怀疑这是这里的问题。

但是,然后我尝试在 main 的调用点显式指定模板参数:

mwrite<std::string, std::ostream&>(std::string("Hello"), out, err);

这也很好用。因此,我发现自己处于编译器在特定特化(具有按值传递 ostreams 的特化)上失败的情况,而确实存在一个完全合法的特化(具有按引用传递 ostreams)。我不愿意责怪编译器,所以我的问题是:这种行为是否仍然符合 SFINAE 标准?我是不是误会了什么?

最佳答案

这与SFINAE无关。无论如何,这里没有替换失败。 SFINAE 与创建格式错误的函数声明的模板参数替换有关。签名 void mwrite(std::string, std::ostream&, std::ostream); 没有任何格式错误。

问题是您正在按值传递 SS,因此最终会尝试制作流的拷贝。流不可复制。而是通过引用传递:

template <typename T, typename... SS>
void mwrite(T value, std::ostream& os, SS&... streams) { mwrite(value, os); mwrite(value, streams...); }
// ^

关于c++ - VS2013 上的模板特化和 SFINAE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28719332/

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