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

用模板类专门化模板函数

  •  1
  • for_stack  · 技术社区  · 8 年前

    我需要写一个 parse 可以分析的函数 string 对于其他类型:

    OtherType parse(const std::string &s)
    

    由于C++不允许通过返回值重载,我尝试使用模板和模板专门化:

    template <typename T>
    T parse(const std::string &s);
    
    template <>
    double parse(const std::string &s) { return std::stod(s); }
    

    这是可行的,但是,我还需要用 template <typename T, typename U> std::pair<T, U> template <typename ...Args> std::tuple<Args...> 。显然,以下 不会的 工作:

    template <>
    template <typename T, typename U>
    std::pair<T, U> parse(const std::string &s);
    

    请勿 要修改 作语法分析 接口如下,并重载此函数。

    template <typename T>
    void parse(const std::string &s, T &t);
    

    为了保持界面,我尝试了以下方法:

    template <typename ...>
    struct Trait {};
    
    double parse_impl(Trait<double>, const std::string &s);
    
    template <typename T, typename U>
    std::pair<T, U> parse_impl(Trait<std::pair<T, U>>, const std::string &s);
    
    template <typename T>
    T parse(const std::string &s) {
        return parse_impl(Trait<T>(), s);
    }
    

    虽然这很好,但我想知道有没有更好的解决方案?有没有语法糖可以帮助我写下这样的东西: template <> template <typename T, typename U> std::pair<T, U> parse(const std::string &s);

    2 回复  |  直到 8 年前
        1
  •  1
  •   songyuanyao    8 年前

    您可以使用类模板,它支持 partial template specialization ;而函数模板没有。例如。

    template <typename T>
    struct parser {
        static T parse(const std::string &s);
    };
    
    template <>
    struct parser<double> {
        static double parse(const std::string &s) {
            return std::stod(s);
        }
    };
    
    template <typename T, typename U>
    struct parser<std::pair<T, U>> {
        static std::pair<T, U> parse(const std::string &s) {
            return ...;
        }
    };
    
    template <typename... Args>
    struct parser<std::tuple<Args...>> {
        static std::tuple<Args...> parse(const std::string &s) {
            return ...;
        }
    };
    

    并添加助手函数模板,

    template <typename... T>
    inline auto parse(const std::string& s) {
        return parser<T...>::parse(s);
    }
    

    并将其用作,

    parse<double>("");
    parse<std::pair<int, int>>("");
    parse<std::tuple<int, int, int>>("");
    

    LIVE

        2
  •  0
  •   xskxzr    8 年前

    即使函数模板的参数相同,也可以重载它们,所以只需使用

    // overloading, not specialization
    template <typename T, typename U>
    std::pair<T, U> parse(const std::string &s);