V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iqoo
V2EX  ›  程序员

C++ 可根据参数值进行重载吗?

  •  
  •   iqoo · 2023-07-11 11:20:25 +08:00 · 1763 次点击
    这是一个创建于 501 天前的主题,其中的信息可能已经有所发展或是发生改变。
    函数或类方法,当参数为常量 1 时返回类型 A ,参数为常量 2 时返回类型 B ,并且在编译期间确定。

    在一些语言例如 TypeScript 中,参数类型可以是一个常量或常量集合,返回类型也可根据参数确定。这在 C++ 中实现不了吧。
    18 条回复    2023-07-11 17:24:16 +08:00
    wanmyj
        1
    wanmyj  
       2023-07-11 11:31:38 +08:00
    不可以
    agagega
        2
    agagega  
       2023-07-11 11:33:10 +08:00 via iPhone
    你把常量的值当作一个模板参数然后特化就可以了。
    wanmyj
        3
    wanmyj  
       2023-07-11 11:33:26 +08:00
    如果你说的参数值是参数的个数的话,那是可以的,只是每种参数组合自己都实现一遍就好了
    nightwitch
        4
    nightwitch  
       2023-07-11 11:33:54 +08:00 via Android
    返回参数用 std::variant 。 传入参数如果是编译期常量的话可以用 if constexpr
    ProPh3t
        5
    ProPh3t  
       2023-07-11 11:33:56 +08:00   ❤️ 1
    template + auto 应该就可以满足吧
    iOCZ
        6
    iOCZ  
       2023-07-11 11:37:02 +08:00
    理论上如果是常量是可以实现的,编译时就知道调用哪个了
    cxxnullptr
        7
    cxxnullptr  
       2023-07-11 11:41:10 +08:00
    #include <iostream>

    template<int N>
    void func() {
    std::cout << "default: None" << std::endl;
    }

    template <>
    void func<1>() {
    std::cout << "func: 1" << std::endl;
    }

    template <>
    void func<2>() {
    std::cout << "func: 2" << std::endl;
    }

    int main(int argc, char *argv[]) {
    func<0>();
    func<1>();
    func<2>();

    return 0;
    }
    cxxnullptr
        8
    cxxnullptr  
       2023-07-11 11:51:33 +08:00
    @cxxnullptr 看错了,没注意到返回不同类型
    hankai17
        9
    hankai17  
       2023-07-11 12:11:32 +08:00
    这个 模板元编程里很常见吧 原理就是 SFINAE
    此外 还有一些面向编译期的操作 constexpr enable_if decltype ...
    tool2d
        10
    tool2d  
       2023-07-11 12:15:36 +08:00
    C++是强类型的语言。要做弱类型的语法兼容,只能自己写一个类似 QT MOC 这种 preprocesser 做源代码预处理工具。

    C++是一个上限下限都很高的语言,可以随便折腾。
    tool2d
        11
    tool2d  
       2023-07-11 12:18:19 +08:00
    单单是 OP 的特定需求,直接用 VARIANT 呗,COM 里接口都是多类型的参数。
    xtreme1
        12
    xtreme1  
       2023-07-11 12:19:22 +08:00
    #include <concepts>
    #include <iostream>

    using namespace std::literals;

    template<auto x>
    auto f() {
    if constexpr (x == 42)
    return 42;
    else
    return "oops"s;
    }

    auto main() -> int {
    auto x = f<1>();
    auto y = f<42>();

    static_assert(std::same_as<decltype(x), std::string>);
    static_assert(std::same_as<decltype(y), int>);

    std::cout << "x: " << x << std::endl;
    std::cout << "y: " << y << std::endl;
    }
    Inn0Vat10n
        13
    Inn0Vat10n  
       2023-07-11 12:23:31 +08:00
    jqknono
        14
    jqknono  
       2023-07-11 12:42:21 +08:00
    C++ 不可以根据**参数值**进行重载, C++ 可以根据**参数类型**进行重载, 使用模板方法实现.
    C++返回值类型虽然是固定的, 但是可以返回指针类型(void*), 指向什么类型就可以任意转换了, 也就是返回值的真实类型不在返回时确定, 而是在使用时确定.

    C++属于是更靠近底层的语言, 只有部分汇编微码能做的事它做不到, nodejs 是 C++写的, 只要 nodejs 能做的, C++就能做. 语言的依赖方向是高级语言依赖低级语言, 从低级抽象到高级. ts 能做的所有事汇编都能做, 只是路程很远, 反过来才是做不到的.
    chendl111
        15
    chendl111  
       2023-07-11 12:46:28 +08:00
    在 C++中,函数或类方法不能通过参数值来进行重载。重载是指在同一个作用域中定义多个具有相同名称但参数列表不同的函数或类方法。重载的目的是为了提供不同的参数组合,以便在不同的情况下使用正确的函数或方法。

    参数的类型和数量是用于重载函数或类方法的主要标识符。因此,如果你只是改变参数的值,而不改变其类型或数量,编译器将无法区分这两个函数或方法,并且会导致编译错误。

    当需要根据参数值进行编译期间确定返回类型时,可以考虑使用模板特化来实现。通过使用模板特化,你可以为特定的常量参数值提供不同的返回类型。

    以下是一个示例,演示如何使用模板特化来根据常量参数值返回不同的类型:

    cpp
    template <int N>
    struct ReturnType {
    // 默认返回类型
    using Type = void;
    };

    template <>
    struct ReturnType<1> {
    // 当参数为常量 1 时返回类型 A
    using Type = A;
    };

    template <>
    struct ReturnType<2> {
    // 当参数为常量 2 时返回类型 B
    using Type = B;
    };

    // 使用示例
    template <int N>
    typename ReturnType<N>::Type returnTypeFunction() {
    // 返回特定的类型
    return typename ReturnType<N>::Type();
    }

    // 调用函数
    auto result1 = returnTypeFunction<1>(); // 返回类型 A
    auto result2 = returnTypeFunction<2>(); // 返回类型 B
    在上面的示例中,我们使用模板特化来为常量参数值 1 和 2 提供不同的返回类型。returnTypeFunction()函数根据传递的常量参数值调用相应的特化版本,并返回相应的类型。

    请注意,这只是一种在 C++中根据参数值确定返回类型的方法之一。具体实现可能因你的需求而有所不同。
    mogg
        16
    mogg  
       2023-07-11 13:57:30 +08:00
    当然可以了,看看 std::get<Index>(tuple) 是怎么做的

    https://en.cppreference.com/w/cpp/utility/tuple/get
    chuhades
        17
    chuhades  
       2023-07-11 14:17:11 +08:00
    模板特化
    kkhaike
        18
    kkhaike  
       2023-07-11 17:24:16 +08:00
    17 以上直接用 constexpr
    以下用 enable_if
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   944 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 20:55 · PVG 04:55 · LAX 12:55 · JFK 15:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.