我引用此link来实施variadic template:
#include <iostream>
#include <sstream>
// base case
void doPrint(std::ostream &out) {}
template <typename T, typename... Args>
void doPrint(std::ostream &out, T t, Args... args)
{
out << t; // add comma here, see below
doPrint(out, args...);
}
int main() {
// See how it works even better than varargs?
doPrint(std::cout, "Hola", " mundo ");
return 0;
}
但如果我从参考
更改功能参数void doPrint(std::ostream &out)
......
template <typename T, typename... Args>
void doPrint(std::ostream &out, T t, Args... args)
值:
void doPrint(std::ostream out)
......
template <typename T, typename... Args>
void doPrint(std::ostream out, T t, Args... args)
我收到以下构建错误:
test.cpp: In function 'int main()':
test.cpp:16:40: error: 'std::basic_ostream<_CharT, _Traits>::basic_ostream(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]' is protected within this context
doPrint(std::cout, "Hola", " mundo ");
^
In file included from /usr/include/c++/7.1.1/iostream:39:0,
from test.cpp:1:
/usr/include/c++/7.1.1/ostream:391:7: note: declared protected here
basic_ostream(const basic_ostream&) = delete;
^~~~~~~~~~~~~
test.cpp:16:40: error: use of deleted function 'std::basic_ostream<_CharT, _Traits>::basic_ostream(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
doPrint(std::cout, "Hola", " mundo ");
^
In file included from /usr/include/c++/7.1.1/iostream:39:0,
from test.cpp:1:
/usr/include/c++/7.1.1/ostream:391:7: note: declared here
basic_ostream(const basic_ostream&) = delete;
^~~~~~~~~~~~~
test.cpp:8:6: note: initializing argument 1 of 'void doPrint(std::ostream, T, Args ...) [with T = const char*; Args = {const char*}; std::ostream = std::basic_ostream<char>]'
void doPrint(std::ostream out, T t, Args... args)
^~~~~~~
test.cpp: In instantiation of 'void doPrint(std::ostream, T, Args ...) [with T = const char*; Args = {const char*}; std::ostream = std::basic_ostream<char>]':
test.cpp:16:40: required from here
test.cpp:11:12: error: 'std::basic_ostream<_CharT, _Traits>::basic_ostream(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]' is protected within this context
doPrint(out, args...);
~~~~~~~^~~~~~~~~~~~~~
In file included from /usr/include/c++/7.1.1/iostream:39:0,
from test.cpp:1:
/usr/include/c++/7.1.1/ostream:391:7: note: declared protected here
basic_ostream(const basic_ostream&) = delete;
^~~~~~~~~~~~~
test.cpp:11:12: error: use of deleted function 'std::basic_ostream<_CharT, _Traits>::basic_ostream(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
doPrint(out, args...);
~~~~~~~^~~~~~~~~~~~~~
In file included from /usr/include/c++/7.1.1/iostream:39:0,
from test.cpp:1:
/usr/include/c++/7.1.1/ostream:391:7: note: declared here
basic_ostream(const basic_ostream&) = delete;
^~~~~~~~~~~~~
test.cpp:8:6: note: initializing argument 1 of 'void doPrint(std::ostream, T, Args ...) [with T = const char*; Args = {}; std::ostream = std::basic_ostream<char>]'
void doPrint(std::ostream out, T t, Args... args)
^~~~~~~
根据我的理解,使用值可能没有良好的性能作为参考,但它不应该导致编译错误。为什么C ++ variadic模板不接受iostream
值作为参数?
答案 0 :(得分:5)
这很简单,因为std::basic_ostream
中的复制构造函数被删除(按标准)
阅读此here at cppreference。
所以std::cout
你可以移动或参考
示例:
class A {
public:
A(const A& a) = delete;
};
void foo1(const A& a)
{
std::cout << "HEY1" << std::endl;
}
void foo2(const A a)
{
std::cout << "HEY2" << std::endl;
}
int main() {
A a{};
foo1(a);
// foo2(a);
return 0;
}
因此,在示例中,您会看到第一个函数在删除复制构造函数时工作正常,但如果取消注释foo2(a)
,则可以从编译中获取一些信息,例如: (VS)
'A :: A(const A&amp;)':尝试引用已删除的函数
答案 1 :(得分:2)
解释是在前几行错误消息中。
std::ostream
实际上是typedef
的{{1}}。
按值传递std::basic_ostream<char, std::char_traits<char> >
会调用对象的复制构造函数,std::ostream
模板已明确删除了复制构造函数,因此无法调用它。