You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在函数模板中使用Parser别名模板实现通用Try函数?

通用Try函数模板的正确实现

要实现你想要的Try<Digit>(r, "0")调用方式,核心是把目标函数作为非类型模板参数传入,同时让编译器自动推导函数的返回类型,避免重复指定类型。以下是两种可行的实现方案:

方案1:C++17及以上(推荐,最简洁)

利用C++17引入的auto非类型模板参数,直接推导函数指针类型,再通过std::invoke_result_t获取函数返回类型:

#include <string>
#include <type_traits>
#include <stdexcept>
#include <cctype>

template<typename T>
using Parser = T(* const)(std::string const &);

char Digit(std::string const &str) {
    if (str.size() != 1 || !isdigit(str[0])) {
        throw std::invalid_argument("Not a digit");
    }
    return str[0];
}

template <auto p>
bool Try(typename std::invoke_result_t<decltype(p), const std::string&>& result, const std::string& str) {
    static_assert(p != nullptr, "Parser cannot be null.");

    try {
        result = p(str);
        return true;
    } catch (const std::exception& e) {
        return false;
    }
}

int main() {
    char r;
    Try<Digit>(r, "0"); // 完全符合你的调用需求
}

说明:

  • template <auto p>:让编译器自动推导模板参数p的类型,这里p直接绑定Digit函数的指针。
  • std::invoke_result_t<decltype(p), const std::string&>:通过函数指针类型和参数类型,自动推导函数的返回类型(此处为char),确保result的类型与函数返回值匹配。

方案2:兼容C++11/14

如果无法使用C++17,可以显式指定返回类型和函数指针作为模板参数,调用时需同时声明返回类型:

#include <string>
#include <stdexcept>
#include <cctype>

template<typename T>
using Parser = T(* const)(std::string const &);

char Digit(std::string const &str) {
    if (str.size() != 1 || !isdigit(str[0])) {
        throw std::invalid_argument("Not a digit");
    }
    return str[0];
}

template <typename T, Parser<T> p>
bool Try(T& result, const std::string& str) {
    static_assert(p != nullptr, "Parser cannot be null.");

    try {
        result = p(str);
        return true;
    } catch (const std::exception& e) {
        return false;
    }
}

int main() {
    char r;
    Try<char, Digit>(r, "0"); // 需显式指定返回类型T
}

说明:

  • template <typename T, Parser<T> p>:先指定返回类型T,再指定符合Parser<T>类型的函数指针p。
  • 这种方式兼容更早的C++标准,但调用时需要额外显式声明返回类型。

核心要点

  • 非类型模板参数直接绑定函数指针,确保编译期就能通过static_assert检查函数是否为空。
  • 利用类型推导或std::invoke_result_t简化调用,避免重复编写返回类型代码。

内容的提问来源于stack exchange,提问作者heheheha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:35:04