user12581835
user12581835

Reputation:

How can I give alternative names to functions?

Let's say I have a function called get_color:

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

I also want to have the same function but with the en-gb spelling, which is get_colour. I could just make an identical function and call the get_color function like this:

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

but this can get very tricky to maintain. Is there any other way to give a second name to a function?

Upvotes: 1

Views: 690

Answers (6)

t.niese
t.niese

Reputation: 40842

I only write it here as an answer because I can't mark it as a duplicate to C++11: How to alias a function? or How do I assign an alias to a function name in C++? again.

Making an alias can be done using:

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);

The advantage over:

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

is that the compiler will know for the constexpr/const version that get_colour won't change, so it can directly map the get_colour call to get_color. For the none constexpr version you will have an indirection over the stored pointer.

If you have

#include <iostream>
#include <string>

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

auto get_colour = get_color;

int main() {
  std::cout << get_colour() << "\n";
}

You can see that at the [QWORD PTR get_colour[abi:cxx11][rip]] that the is not inlined, because get_colour could changed:

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*)

But for the constexpr version:

#include <iostream>
#include <string>

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

constexpr auto get_colour = get_color;

int main() {
  std::cout << get_colour() << "\n";
}

The function call to get_colour can be inlined (get_color[abi:cxx11]() is not called) but the generated code directly appears in 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*)

Or use perfect forwarding which will work for both free and member functions:

void get_color() {
}

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

For c++11 -> decltype(get_color(std::forward<Args>(args)...)) needs to be added:

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

Upvotes: 2

user12581835
user12581835

Reputation:

This what I ended up doing:

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

Note: This only works with C++ 14 or higher

Upvotes: 0

Omkar76
Omkar76

Reputation: 1628

You can also use reference variable.

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

auto & get_colour = get_color;

Upvotes: 0

Galilean
Galilean

Reputation: 268

In cpp11 you can use the functional standard library, this fulfils your requirement

#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;
    }

For more info have a look here

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234695

auto get_colour(get_color);

is one way. Needs a little more thought if you want to support overloaded functions.

Upvotes: 3

Aaron D. Marasco
Aaron D. Marasco

Reputation: 6748

A C-style macro would work, but I'm not a fan of macros.

#define get_colour(x) get_color(x)

Upvotes: 3

Related Questions