代码之家  ›  专栏  ›  技术社区  ›  PiotrNycz

数组到指针类模板参数的推导适用于模板指南,但不适用于非模板版本,这是正确的还是错误的?

  •  5
  • PiotrNycz  · 技术社区  · 6 年前

    我有一个类模板,带有一个类型param和 const char* 键入完全专用化,下面是简化的示例:

    template <typename T>
    struct PrettyPrint {
        PrettyPrint(const T& value) : value(value) {}
        const T& value;
        friend std::ostream& operator << (std::ostream& os, const PrettyPrint& pp) {
            return os << "(" << pp.value << ")";
        }
    };
    template <>
    struct PrettyPrint<const char*> {
        PrettyPrint(const char* value) : value(value) {}
        const char* value;
        friend std::ostream& operator << (std::ostream& os, const PrettyPrint& pp) {
            return os << "\"" << pp.value << "\"";
        }
    };
    

    简而言之-打印如下字符字符串 "abc" 所有其他的价值观 (123) ( "" VS () )

    所以,我补充说,作为对所有 char[N] A类扣款指南:

    template <std::size_t N>
    PrettyPrint(char(&)[N]) -> PrettyPrint<const char*>; //deduction guide
    

    不幸的是,它不起作用:

     std::cout << PrettyPrint(7) << PrettyPrint("aaa") << PrettyPrint((const char*)"bbb");
    

    (7)(AAA)“BBB”

    预期产量:

    (7)“AAA”“BBB”

    但是,令人惊讶的是,这样做:

    template <typename T, std::size_t N>
    PrettyPrinter(T(&)[N]) -> PrettyPrinter<const T*>; //deduction guide
    
     std::cout << PrettyPrint(7) << PrettyPrint("aaa") << PrettyPrint((const char*)"bbb");
    

    (7)“AAA”“BBB”

    所以问题是:

    1. 这是正确的(那么为什么)还是编译器中的一个bug(用gcc/clang-最新版本测试)
    2. 如果这是正确的-那么如何限制这个模板演绎指南 char 只有?
    2 回复  |  直到 6 年前
        1
  •  7
  •   Rakete1111    6 年前

    这是意料之中的。字符串文字具有类型 const char[N] . 注意 const . const值不能绑定到非const引用,因此实际上没有选择演绎指南,而是实例化主模板。

    template <std::size_t N>
    PrettyPrint(const char(&)[N]) -> PrettyPrint<const char*>;
    

    你的第二个演绎指南很有用,因为在这里, T 被推断为 const char ,非常好。

        2
  •  7
  •   NathanOliver    6 年前

    这里的问题是字符串文字是 const char[N] ,不是 char[N] . 将指南更改为

    template <std::size_t N>
    PrettyPrint(const char(&)[N]) -> PrettyPrint<const char*>; //deduction guide
    

    会给你预期的结果。