从STD :: BITSET ::操作员[]扣除模板

Template deduction from std::bitset::operator[]

本文关键字:STD BITSET 操作员      更新时间:2023-10-16

该代码如何不编译?为什么不能将bs[1]推入bool

是否有一种通用方法可以解决此问题?

#include <iostream>
#include <string>
#include <bitset>
using namespace std;
template<typename T> struct StringConverter{};
template<> struct StringConverter<bool>{
    std::string operator()(const bool &i){ return i?"true":"false"; }   
};
template<typename T> std::string to_string(const T &val){
    return StringConverter<T>()(val);
}
int main(){
    // this does not compile
    std::bitset<10> bs;
    std::cout << to_string(bs[0]) << std::endl;
    // this does
    const std::bitset<10> bs_const;
    std::cout << to_string(bs_const[0]) << std::endl;
}

编译器错误:

main.cpp:12:12: error: type 'StringConverter<std::bitset<10>::reference>' does not provide a call operator
    return StringConverter<T>()(val);
           ^~~~~~~~~~~~~~~~~~~~
main.cpp:18:18: note: in instantiation of function template specialization 'to_string<std::bitset<10>::reference>' requested here
    std::cout << to_string(bs[0]) << std::endl;
                 ^
1 error generated.

non-const bitset :: operator []返回代理对象而不是bool(必须这样做,因为该代理可用于更改位值)。const bittet :: operator []但是,只返回一个布尔(不是参考,只是一个普通的布尔),因此它与StringConverter [

如果您检查了operator[]的声明,您会注意到它具有两个过载 - const一个,它返回bool,并在您的第二个示例中使用,而非const则使用返回类型std::bitset::reference的对象。

后者用于BIT字段修改,并且绝对不能是bool&,因为它必须解决特定位。对于这些代理返回类型,您遇到的问题很常见(这是我应该提到的vector<bool>)。

作为一种可能的解决方案,您可以使用std::bitset::reference可转换为bool的事实(并且无法转换为您可能用于StringConverter专业的任何其他可能的类型)。