【问题标题】:How can I give alternative names to functions?如何为函数提供替代名称?
【发布时间】:2020-09-04 12:29:12
【问题描述】:

假设我有一个名为get_color的函数:

std::string get_color()
{
    return "green";
}

我也想拥有相同的功能,但使用 en-gb 拼写,即get_colour。我可以创建一个相同的函数并像这样调用 get_color 函数:

std::string get_colour()
{
    return get_color()
}

但这可能会变得非常难以维护。有没有其他方法可以给函数起第二个名字?

【问题讨论】:

标签: c++ function alias


【解决方案1】:
auto get_colour(get_color);

是一种方式。如果您想支持重载函数,则需要更多考虑。

【讨论】:

    【解决方案2】:

    C 风格的宏可以工作,但我不喜欢宏。

    #define get_colour(x) get_color(x)

    【讨论】:

    • 应该使用__VA_ARGS__
    【解决方案3】:

    我只在这里写它作为答案,因为我无法将其标记为与C++11: How to alias a function?How do I assign an alias to a function name in C++? 的重复。

    可以使用以下方法创建别名:

    constexpr auto get_colour = get_color;
    // or
    constexpr auto get_colour(get_color);
    
    const auto get_colour = get_color;
    // or
    const auto get_colour(get_color);
    

    优势:

    auto get_colour = get_color;
    // OR
    auto get_colour(get_color);
    

    是编译器将知道constexpr/const 版本不会更改get_colour,因此它可以直接将get_colour 调用映射到get_color。对于 none constexpr 版本,您将对存储的指针进行间接处理。

    如果你有

    #include <iostream>
    #include <string>
    
    std::string get_color()
    {
        return "green";
    }
    
    auto get_colour = get_color;
    
    int main() {
      std::cout << get_colour() << "\n";
    }
    

    您可以在 [QWORD PTR get_colour[abi:cxx11][rip]] 看到未内联的,因为 get_colour 可能会更改:

    get_color[abi:cxx11]():
            lea     rdx, [rdi+16]
            mov     BYTE PTR [rdi+20], 110
            mov     rax, rdi
            mov     QWORD PTR [rdi], rdx
            mov     DWORD PTR [rdi+16], 1701147239
            mov     QWORD PTR [rdi+8], 5
            mov     BYTE PTR [rdi+21], 0
            ret
    .LC0:
            .string "\n"
    main:
            push    rbp
            sub     rsp, 32
            mov     rdi, rsp
            call    [QWORD PTR get_colour[abi:cxx11][rip]]
            mov     rdx, QWORD PTR [rsp+8]
            mov     rsi, QWORD PTR [rsp]
            mov     edi, OFFSET FLAT:_ZSt4cout
            call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
            mov     rdi, rax
            mov     edx, 1
            mov     esi, OFFSET FLAT:.LC0
            call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
            mov     rdi, QWORD PTR [rsp]
            lea     rax, [rsp+16]
            cmp     rdi, rax
            je      .L8
            call    operator delete(void*)
    

    但对于constexpr 版本:

    #include <iostream>
    #include <string>
    
    std::string get_color()
    {
        return "green";
    }
    
    constexpr auto get_colour = get_color;
    
    int main() {
      std::cout << get_colour() << "\n";
    }
    

    get_colour的函数调用可以内联(get_color[abi:cxx11]()不被调用)但是生成的代码直接出现在main:中:

    get_color[abi:cxx11]():
            lea     rdx, [rdi+16]
            mov     BYTE PTR [rdi+20], 110
            mov     rax, rdi
            mov     QWORD PTR [rdi], rdx
            mov     DWORD PTR [rdi+16], 1701147239
            mov     QWORD PTR [rdi+8], 5
            mov     BYTE PTR [rdi+21], 0
            ret
    .LC0:
            .string "\n"
    main:
            push    rbp
            mov     edx, 5
            mov     edi, OFFSET FLAT:_ZSt4cout
            push    rbx
            sub     rsp, 40
            lea     rbx, [rsp+16]
            mov     BYTE PTR [rsp+20], 110
            mov     rsi, rbx
            mov     QWORD PTR [rsp], rbx
            mov     DWORD PTR [rsp+16], 1701147239
            mov     QWORD PTR [rsp+8], 5
            mov     BYTE PTR [rsp+21], 0
            call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
            mov     rdi, rax
            mov     edx, 1
            mov     esi, OFFSET FLAT:.LC0
            call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
            mov     rdi, QWORD PTR [rsp]
            cmp     rdi, rbx
            je      .L8
            call    operator delete(void*)
    

    或者使用对免费和会员功能都适用的完美转发:

    void get_color() {
    }
    
    template <typename... Args>
    auto get_colour(Args&&... args) {
      return get_color(std::forward<Args>(args)...);
    }
    

    对于c++11需要添加 -&gt; decltype(get_color(std::forward&lt;Args&gt;(args)...))

    template <typename... Args>
    auto get_colour(Args&&... args) -> decltype(get_color(std::forward<Args>(args)...)) {
      return get_color(std::forward<Args>(args)...);
    }
    

    【讨论】:

    【解决方案4】:

    在cpp11中你可以使用功能标准库,这满足你的要求

    #include <functional>
    #include <iostream>
    #include<string>
    
        std::string func()
        {
        return "hello";
        }
        
        int main()
        {
        std::function<std::string()> newfunc = func;
        
        std::cout << newfunc() << std::endl;
        
        return 0;
        }
    

    更多信息请查看here

    【讨论】:

    • 这并没有真正创建别名,并且不利于优化。但最重要的是,如果不符合 OP 的要求:but this can get very tricky to maintain. Is there any other way to give a second name to a function?whenever you want to change the function parameters, you will have to change the first function and the second,以防 func 的签名发生变化。
    【解决方案5】:

    你也可以使用引用变量。

    std::string get_color(){
        return "green";
    }
    
    auto & get_colour = get_color;
    
    

    【讨论】:

      【解决方案6】:

      这就是我最终做的:

      template<typename... Args>
      auto get_colour(Args&&... args)
      {
        return get_color(static_cast<Args>(args)...);
      }
      

      注意:这只适用于 C++ 14 或更高版本

      【讨论】:

        猜你喜欢
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-25
        • 2017-02-04
        • 2018-10-12
        • 1970-01-01
        相关资源
        最近更新 更多