我编写了一个打印模板函数,它为bool类型值打印"True"
或"False"
。
我尝试将其应用于for_each
算法,但它不起作用。
输出仍为0
或1
。似乎模板专业化在for_each
中不起作用。怎么会发生这种情况?
如何使代码按预期工作?
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <ctime>
using namespace std;
template <typename T>
void _print(const T& i)
{
cout<<i<<endl;
}
template <>
void _print<bool>(const bool& i)
{
if (i == 0)
cout<<"False"<<endl;
else
cout<<"True"<<endl;
}
class print
{
public:
template <typename T>
void operator()(const T& val) const { _print(val); };
};
int main()
{
auto even = [&](int i)->bool{return (i%2==0);};
srand(time(NULL));
vector <int> test(3);
generate(test.begin(),test.end(),[]()->int{return rand()%100;});
for_each(test.begin(),test.end(),print());
vector <bool> flag(3);
transform(test.begin(),test.end(),flag.begin(),even);
for_each(flag.begin(),flag.end(),print());
return 0;
}
输出结果为:
34
23
3
1
0
0
但我希望:
34
23
3
True
False
False
答案 0 :(得分:10)
std::vector<bool>
的邪恶部分
vector<bool>::reference
不是您所期望的bool
,而是代理。
您可以添加额外的超载(如果您愿意,可以添加专业化):
void _print(const vector<bool>::reference& i)
{
_print<bool>(i);
}
答案 1 :(得分:4)
问题是vector<bool>
不是bool
的容器。相反,它将多个“布尔”值打包到其存储的每个字节中,因此无法获得对任何bool
值的引用。相反,取消引用迭代器会提供类型为vector<bool>::reference
的“代理”对象,其行为类似于bool
在某些情况下的引用,但并非所有情况。
在这种情况下,这还不够好;您对_print
的专业化需要真正的const bool&
引用,但_print
会传递reference
类型的对象,从中推断出通用模板。
您可以通过为此类型添加重载来支持vector<bool>
作为特殊情况:
void _print(std::vector<bool>::reference r) {_print(bool(r));}
(顺便说一句,您不应该使用_print
之类的reserved names