Reputation:
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
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
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
Reputation: 1628
You can also use reference variable.
std::string get_color(){
return "green";
}
auto & get_colour = get_color;
Upvotes: 0
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
Reputation: 234695
auto get_colour(get_color);
is one way. Needs a little more thought if you want to support overloaded functions.
Upvotes: 3
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