C++ 自由函数可以别名吗?
Can C++ free functions be aliased?
我有一个命名空间,其中包含一个高度模板化的免费函数,例如:
namespace a
{
template<typename T, typename K, typename H>
void f(T t, K k, std::vector<H> h_vec = {})
{ /* body */ }
}
在另一个命名空间内,为了方便起见,我想为它的一些特定用途设置一些别名,例如:
namespace b
{
using my_specific_f = a::f<int,string,char>;
}
这将使我能够为函数提供更好的命名,因为 f
在我正在处理的代码库中非常通用(请记住,我在这里只提供简化的示例来使观点)。
但不幸的是,这显然是语言所禁止的。
所以在我的第二次尝试中,我尝试使用函数指针:
namespace b
{
auto my_specific_f = &a::f<int,string,char>
}
这通常会起作用,但在我的例子中它不起作用,因为 f
有一个默认参数,我猜这会导致函数有多个函数指针(在本例中为两个),并且只有可以使用三参数版本。
在这一点上我只是放弃并简单地使 my_specific_f
将其主体中的调用重定向到 f
:
namespace b
{
void my_specific_f(int i, string s, vector<char> v = {} )
{
a::f(i,s,v);
}
}
但我不太喜欢这个解决方案,因为它导致可维护性降低,以防万一 f
将更改其签名,因为所有重定向功能都需要协调一致,而我最初的计划是创建更多不仅仅是一个别名。
还有什么我可以尝试的吗?在标准的未来版本中是否有可能或将有可能?
您可以做的是将函数包装在一个通用的 lambda 中,这样您就可以给它一个自定义名称。你可以这样做
auto my_really_informative_name = [](auto&&... args) -> decltype(auto) {
return f(std::forward<decltype(args)>(args)...);
};
这完美地将参数转发给 f
,如果它的签名发生变化,它仍然可以工作,因为 lambda 可以接受任意数量的参数。
如果你想完美转发(没有excecpt限定并且return以SFINAE方式输入)
auto my_really_informative_name = [](auto&&... args) noexcept(noexcept(f(std::forward<decltype(args)>(args)...))) -> decltype(f(std::forward<decltype(args)>(args)...)) {
return f(std::forward<decltype(args)>(args)...);
};
如果您想确保传递给函数的类型是特定类型,那么您可以在函数调用中明确指定它们,例如
auto my_really_informative_name = [](auto&&... args) -> decltype(auto) {
return f<int, std::string, char>(std::forward<decltype(args)>(args)...);
};
我有一个命名空间,其中包含一个高度模板化的免费函数,例如:
namespace a
{
template<typename T, typename K, typename H>
void f(T t, K k, std::vector<H> h_vec = {})
{ /* body */ }
}
在另一个命名空间内,为了方便起见,我想为它的一些特定用途设置一些别名,例如:
namespace b
{
using my_specific_f = a::f<int,string,char>;
}
这将使我能够为函数提供更好的命名,因为 f
在我正在处理的代码库中非常通用(请记住,我在这里只提供简化的示例来使观点)。
但不幸的是,这显然是语言所禁止的。
所以在我的第二次尝试中,我尝试使用函数指针:
namespace b
{
auto my_specific_f = &a::f<int,string,char>
}
这通常会起作用,但在我的例子中它不起作用,因为 f
有一个默认参数,我猜这会导致函数有多个函数指针(在本例中为两个),并且只有可以使用三参数版本。
在这一点上我只是放弃并简单地使 my_specific_f
将其主体中的调用重定向到 f
:
namespace b
{
void my_specific_f(int i, string s, vector<char> v = {} )
{
a::f(i,s,v);
}
}
但我不太喜欢这个解决方案,因为它导致可维护性降低,以防万一 f
将更改其签名,因为所有重定向功能都需要协调一致,而我最初的计划是创建更多不仅仅是一个别名。
还有什么我可以尝试的吗?在标准的未来版本中是否有可能或将有可能?
您可以做的是将函数包装在一个通用的 lambda 中,这样您就可以给它一个自定义名称。你可以这样做
auto my_really_informative_name = [](auto&&... args) -> decltype(auto) {
return f(std::forward<decltype(args)>(args)...);
};
这完美地将参数转发给 f
,如果它的签名发生变化,它仍然可以工作,因为 lambda 可以接受任意数量的参数。
如果你想完美转发(没有excecpt限定并且return以SFINAE方式输入)
auto my_really_informative_name = [](auto&&... args) noexcept(noexcept(f(std::forward<decltype(args)>(args)...))) -> decltype(f(std::forward<decltype(args)>(args)...)) {
return f(std::forward<decltype(args)>(args)...);
};
如果您想确保传递给函数的类型是特定类型,那么您可以在函数调用中明确指定它们,例如
auto my_really_informative_name = [](auto&&... args) -> decltype(auto) {
return f<int, std::string, char>(std::forward<decltype(args)>(args)...);
};