Reputation: 16499
EDIT: This question was originally titled "Using std::bind
to create inline function," but that's not really what I'm after: I just want a simple way to alias functions.
I would like to expose std::chrono::high_resolution_clock::now
as a standalone function. That is, I would like to do the following:
auto current_time = std::bind(std::chrono::high_resolution_clock::now);
Unfortunately, since this is in a header file, it results in multiple definitions of current_time
at link-time. Is there a way to return an inline function from std::bind
?
Upvotes: 6
Views: 2395
Reputation: 5518
Here's what I do if I want to create a simple function alias
constexpr auto &&now = std::chrono::high_resolution_clock::now;
and if I want to create a full wrapper alias that will be inlined
template<typename ... Args>
inline constexpr auto now(Args &&... args) -> decltype(std::chrono::high_resolution_clock::now(std::forward<Args>(args)...)){
return std::chrono::high_resolution_clock::now(std::forward<Args>(args)...);
}
The reason why I use a universal reference auto&&
in the alias definition is because of the possibility of addressof(now) == addressof(std::chrono::high_resolution_clock::now)
.
On my system with G++ 4.9.2 running this:
constexpr auto &&now_ref = std::chrono::high_resolution_clock::now;
constexpr auto now_var = std::chrono::high_resolution_clock::now;
template<typename ... Args>
inline constexpr auto now_wrapper(Args &&... args)
-> decltype(std::chrono::high_resolution_clock::now(std::forward<Args>(args)...)){
return std::chrono::high_resolution_clock::now(std::forward<Args>(args)...);
}
int main(int argc, char *argv[]){
std::cout << std::hex << std::showbase;
std::cout << (uintptr_t)std::addressof(std::chrono::high_resolution_clock::now) << '\n';
std::cout << (uintptr_t)std::addressof(now_wrapper<>) << '\n';
std::cout << (uintptr_t)std::addressof(now_var) << '\n';
std::cout << (uintptr_t)std::addressof(now_ref) << '\n';
}
I get the following results:
0x4007c0
0x400a50
0x400ae8
0x4007c0
Showing that only the auto&&
is actually a direct alias of the function, whereas all other methods have some level of indirection. (although, after compilation they may be replaced by inlined function calls. maybe.)
Upvotes: 8
Reputation: 1723
Adding another answer 'cause it takes a very different tack to what you want.
std::bind isn't necessary in this case, because no 'binding' is happening.
However I feel this could lead to some confusing problems down the line, since current_time isn't really an alias in the same way that using delcarations are.
#include <iostream>
#include <chrono>
using namespace std;
auto constexpr current_time = std::chrono::high_resolution_clock::now;
int main() {
auto now = current_time();
cout << std::chrono::system_clock::to_time_t(now) << endl;
return 0;
}
Upvotes: 3
Reputation: 21773
Keep it simple.
const auto current_time = std::chrono::high_resolution_clock::now;
Upvotes: 2
Reputation: 171273
Using GCC it is possible to create a "function alias", but only for functions which are defined in the same translation unit and for which you know the mangled name, so it's not possible to do reliably for std::chrono::high_resolution_clock::now()
See the alias
attribute at https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Upvotes: 2
Reputation: 1723
I don't think there is anyway to do this as bind is not constexpr.
Also lambdas are not constexpr-able.
Edit: there is this trick to make a constexpr-like lambda http://pfultz2.com/blog/2014/09/02/static-lambda/
Upvotes: 3