来自std :: bitset :: operator []的模板推导

时间:2017-12-09 22:06:58

标签: c++ templates std-bitset

这段代码怎么不编译?为什么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.

2 个答案:

答案 0 :(得分:3)

非const bitset :: operator []返回一个代理对象而不是一个bool(必须这样做,因为该代理可用于更改位值)。 const bitset :: operator []但是只返回一个bool(不是引用,只是一个普通的bool)所以它匹配StringConverter [

答案 1 :(得分:1)

如果您选中declaration of operator[],您会发现它有两个重载 - { "description": "This is a description of my site", "lang": "en-US", "name": "The Very Long Title of My Site", "short_name": "MySite", "start_url": ".", "theme_color": "#171c28", "main.css": "wp-content/themes/mikedpad/style.css", "main.js": "wp-content/themes/mikedpad/js/main.js", "manifest.js": "wp-content/themes/mikedpad/js/manifest.js", "vendor.js": "wp-content/themes/mikedpad/js/vendor.js" } 一个,返回const并在第二个示例中使用,而非{ {1}},返回std::bitset::reference类型的对象。

后者用于位字段修改,它绝对不能是bool,因为它必须处理特定位。您遇到的问题对于这些代理返回类型来说非常常见(这是我应该提到的const)。

作为一种可能的解决方案,您可以使用bool&可转换为vector<bool>的事实(并且不能转换为您可能用于std::bitset::reference专精的任何其他可想到的类型)。