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

显式函数专用化的默认模板参数

  •  0
  • user4037635  · 技术社区  · 10 年前

    我希望有一组可以接受任何 uintX_t 变体,而无需复制/粘贴大量代码。到目前为止,我正在尝试使用“标记”来确定要调用的写函数。由于明显的原因, T = unsigned 不起作用,因为我可能 uint32_t , uint16_t

    struct number_tag {};
    struct hexadecimal : number_tag {};
    struct number : number_tag {};
    
    template <typename T = unsigned, typename Tag>
    void write(T t);
    

    稍后在.cpp文件中:

    template <>
    void write<unsigned, hexadecimal>(unsigned num)
    {
    }
    
    template <>
    void write<unsigned, number>(unsigned num)
    {
    }
    

    理想情况下,我想这样称呼它:

    write<number>(10);
    write("\n");
    write<hexadecimal>(0xFF);
    

    我怎么写这个,这样我就不用做了 write<unsigned, number> 并为每个 单位X_t 变种

    2 回复  |  直到 10 年前
        1
  •  3
  •   John Zwinck    10 年前

    你不能部分专用化函数(boo),但你可以用更多无用的结构来实现!

    struct number_tag {};
    struct hexadecimal : number_tag {};
    struct number : number_tag {};
    
    template <typename Tag, typename T = unsigned>
    struct Writer;
    
    template <typename T>
    struct Writer<hexadecimal, T>
    {
        static void write(T num) {}
    };
    
    template <typename T>
    struct Writer<number, T>
    {
        static void write(T num) {}
    };
    
    template <typename Tag, typename T = unsigned>
    void write(T t)
    {
        Writer<Tag, T>::write(t);
    }
    
    int main()
    {
        write<number>(10);
        write<hexadecimal>(0xFF);
    }
    
        2
  •  1
  •   Piotr Skotnicki    9 年前

    如果要使用单独的 write 专业化取决于 tag ,然后添加重载(因为函数不能部分专用化):

    template <typename T = unsigned>
    void write(T t, hexadecimal tag)
    {
    }
    
    template <typename T = unsigned>
    void write(T t, number tag)
    {
    }
    
    template <typename Tag, typename U = unsigned>
    void write(U num)
    {
        write<U>(num, Tag{});
    }
    
    write<number>(10);
    
    write<hexadecimal>(0xFF);
    
    write<number, std::uint16_t>(0xFF);
    

    DEMO


    如果要向函数添加约束,使其仅接受 无符号的 整数类型,下面的代码会进行正确的验证:

    template <typename Tag, typename U = unsigned>
    auto write(U num) -> typename std::enable_if<std::is_unsigned<U>::value, void>::type
    {
        write<U>(num, Tag{});
    }
    
    write<number>(10u);
    
    //write<number>(-1); // triggers error
    

    DEMO 2

    注: 您当前的声明 template <typename T = unsigned> void write(T t); 不强制 要使用的类型 unsigned ,因为参数的类型是由编译器根据实际参数的类型推断的。


    如果你想强迫 任何类型 传递给 将要执行的功能 无符号的 ,可以使用以下代码:

    template <typename Tag, typename U>
    void write(U num)
    {
        write<typename std::make_unsigned<U>::type>(num, Tag{});
    }
    
    write<number>(-1); // gets converted to unsigned type
    

    DEMO 3