【问题标题】:Template deduction from std::bitset::operator[]来自 std::bitset::operator[] 的模板推导
【发布时间】:2018-05-23 20:11:48
【问题描述】:

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

【问题讨论】:

    标签: c++ templates std-bitset


    【解决方案1】:

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

    【讨论】:

    • 是否有可能以某种方式匹配模板中的代理运算符?
    • 当然可以,但是您必须专门针对 std::bitset::reference 而不是 bool。
    • template&lt;size_t N&gt; struct StringConverter&lt;std::bitset&lt;N&gt;::reference&gt;在clang++下不起作用,因为它说不能扣除N ...
    【解决方案2】:

    如果您检查 declaration of operator[],您会注意到它有两个重载 - const 一个,它返回 bool 并在您的第二个示例中使用,以及非const,它返回std::bitset::reference 类型的对象。

    后者用于位域修改,它绝对不能是bool&amp;,因为它必须针对特定位。对于这些代理返回类型,您遇到的问题很常见(这是我应该提到的vector&lt;bool&gt;)。

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

    【讨论】:

    • 问题是,这会使这个函数成为默认的后备函数,因为很多东西都可以转换为布尔值。例如,如果我有另一个可以打印指针的特化,并使用 std::is_pointer 启用它,并使用 std::is_convertible 启用布尔型,我不确定指针会选择哪一个...
    • 好吧,您可以为指针和数字类型显式禁用它,希望任何其他专业化都能完全匹配。当然,在大量情况下(除了指针/数字)手动禁用它会非常难看。从好的方面来说,它可以与vector&lt;bool&gt;::reference 以及开箱即用的类似工具一起使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多