可以将C ++自由函数用作别名吗?

nya*_*108 4 c++ alias typedef using function-templates

我有一个带有一个高度模板化的免费函数的名称空间,例如:

namespace a
{
    template<typename T, typename K, typename H>
    void f(T t, K k, std::vector<H> h_vec = {})
    { /* body */ }
}
Run Code Online (Sandbox Code Playgroud)

在另一个命名空间中,为了方便起见,我想为一堆特定用法使用一些别名,例如:

namespace b
{
    using my_specific_f = a::f<int,string,char>;
}
Run Code Online (Sandbox Code Playgroud)

这将使我能够为函数提供更好的命名,因为f在我正在研究的代码库中这是非常通用的(请记住,我在这里仅提供简化的示例来说明这一点)。但是不幸的是,这显然是语言所禁止的。

因此,在第二次尝试中,我尝试使用函数指针:

namespace b
{
    auto my_specific_f = &a::f<int,string,char>
}
Run Code Online (Sandbox Code Playgroud)

这通常可以正常工作,但是在我的情况下,由于f没有一个默认参数,因此我认为它不会导致该函数具有一个以上的函数指针(在本例中为两个),并且只能使用三个参数版本。

此时,我只是放弃了,只是简单地my_specific_f将其体内的调用重定向到f

namespace b
{
    void my_specific_f(int i, string s, vector<char> v = {} )
    {
        a::f(i,s,v);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我不太喜欢这种解决方案,因为它会导致较少的可维护性,以防万一f要更改其签名,因为所有重定向功能都需要进行协调调整,而我最初的计划是创建多个别名。

我还有什么可以尝试的吗?在将来的标准发布中甚至可能还是可能?

Nat*_*ica 10

您可以做的是将功能包装在通用lambda中,以便为它指定一个自定义名称。你可以那样做

auto my_really_informative_name = [](auto&&... args) -> decltype(auto) { 
                                      return f(std::forward<decltype(args)>(args)...);
                                  };
Run Code Online (Sandbox Code Playgroud)

这样可以完美地将参数转发给参数,f并且如果其签名发生更改,由于lambda可以接受任意数量的参数,因此它仍然可以使用。

如果您想完美地转发(以SFINAE方式进行noexcecpt限定和返回类型)

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)...);
                                  };
Run Code Online (Sandbox Code Playgroud)

如果要确保传递给函数的类型是某种类型,则可以在函数调用中显式指定它们,例如

auto my_really_informative_name = [](auto&&... args) -> decltype(auto) { 
                                      return f<int, std::string, char>(std::forward<decltype(args)>(args)...);
                                  };
Run Code Online (Sandbox Code Playgroud)