创建函数别名
Creating a function alias
编辑: 这个问题最初的标题是 "Using std::bind
to create inline function," 但这并不是我真正想要的:我只想要一种简单的方法来别名函数。
我想将 std::chrono::high_resolution_clock::now
作为独立函数公开。也就是说,我想做以下事情:
auto current_time = std::bind(std::chrono::high_resolution_clock::now);
不幸的是,由于这是在 header 文件中,因此会导致 link-time 处有多个 current_time
的定义。有没有办法从 std::bind
中 return 一个 内联函数 ?
我不认为无论如何都可以这样做,因为 bind 不是 constexpr。
此外,lambda 表达式不可构造。
编辑:有这个技巧可以制作类似 constexpr 的 lambda http://pfultz2.com/blog/2014/09/02/static-lambda/
添加另一个答案,因为它与您想要的完全不同。
std::bind 在这种情况下不是必需的,因为没有 'binding' 发生。
但是我觉得这可能会导致一些令人困惑的问题,因为 current_time 并不是真正的别名,就像使用 delcarations 一样。
#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;
}
使用 GCC 可以创建 "function alias",但仅限于在同一翻译单元中定义的函数,并且您知道其名称,因此无法可靠地为 std::chrono::high_resolution_clock::now()
请参阅 https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
处的 alias
属性
保持简单。
const auto current_time = std::chrono::high_resolution_clock::now;
如果我想创建一个简单的函数别名,我会这样做
constexpr auto &&now = std::chrono::high_resolution_clock::now;
如果我想创建一个将被内联的完整包装器别名
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)...);
}
之所以在别名定义中使用通用引用auto&&
是因为有可能出现addressof(now) == addressof(std::chrono::high_resolution_clock::now)
.
在我的 G++ 4.9.2 系统上 运行 这个:
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';
}
我得到以下结果:
0x4007c0
0x400a50
0x400ae8
0x4007c0
表明只有 auto&&
实际上是函数的直接别名,而所有其他方法都具有一定程度的间接性。 (尽管在编译之后,它们 可能 被内联函数调用替换。可能。)
编辑: 这个问题最初的标题是 "Using std::bind
to create inline function," 但这并不是我真正想要的:我只想要一种简单的方法来别名函数。
我想将 std::chrono::high_resolution_clock::now
作为独立函数公开。也就是说,我想做以下事情:
auto current_time = std::bind(std::chrono::high_resolution_clock::now);
不幸的是,由于这是在 header 文件中,因此会导致 link-time 处有多个 current_time
的定义。有没有办法从 std::bind
中 return 一个 内联函数 ?
我不认为无论如何都可以这样做,因为 bind 不是 constexpr。
此外,lambda 表达式不可构造。
编辑:有这个技巧可以制作类似 constexpr 的 lambda http://pfultz2.com/blog/2014/09/02/static-lambda/
添加另一个答案,因为它与您想要的完全不同。
std::bind 在这种情况下不是必需的,因为没有 'binding' 发生。
但是我觉得这可能会导致一些令人困惑的问题,因为 current_time 并不是真正的别名,就像使用 delcarations 一样。
#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;
}
使用 GCC 可以创建 "function alias",但仅限于在同一翻译单元中定义的函数,并且您知道其名称,因此无法可靠地为 std::chrono::high_resolution_clock::now()
请参阅 https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
处的alias
属性
保持简单。
const auto current_time = std::chrono::high_resolution_clock::now;
如果我想创建一个简单的函数别名,我会这样做
constexpr auto &&now = std::chrono::high_resolution_clock::now;
如果我想创建一个将被内联的完整包装器别名
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)...);
}
之所以在别名定义中使用通用引用auto&&
是因为有可能出现addressof(now) == addressof(std::chrono::high_resolution_clock::now)
.
在我的 G++ 4.9.2 系统上 运行 这个:
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';
}
我得到以下结果:
0x4007c0
0x400a50
0x400ae8
0x4007c0
表明只有 auto&&
实际上是函数的直接别名,而所有其他方法都具有一定程度的间接性。 (尽管在编译之后,它们 可能 被内联函数调用替换。可能。)