别名std模板函数

che*_*jar 8 c++ stdtuple c++17

我需要别名std::get功能,以提高我的代码的可读性.

不幸的是我遇到了编译时错误get<0> in namespace ‘std’ does not name a type.using相当于typedef它需要使用类型.我用a std::tuple来表示一些数据类型:

using myFoo = std::tuple<int,int,double,string>;
using getNumber = std::get<0>;
Run Code Online (Sandbox Code Playgroud)

我看一些以前的问题,但提出的解决方案是包装和使用std::forward.我不想为每个成员编写这样的代码.

有没有办法只使用关键字解决这个问题?

sky*_*ack 10

有没有办法只使用关键字解决这个问题?

我会说没有,对于std::get是不是一个类型(因此它没有资格获得这样的使用).
此外,即使有可能,请注意这std::get是一个重载函数,因此您需要将自己绑定到特定实现.

也就是说,在C++ 17中,你可以这样做:

#include<tuple>
#include<utility>

using myFoo = std::tuple<int,int,double>;
constexpr auto getNumber = [](auto &&t) constexpr -> decltype(auto) { return std::get<0>(std::forward<decltype(t)>(t)); };

template<int> struct S {};

int main() {
    constexpr myFoo t{0,0,0.};
    S<getNumber(t)> s{};
    (void)s;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,constexprlambdas和变量可以帮助您创建可用于重命名函数的编译时(假设)包装器.


正如@TC在评论中正确指出的那样,如果你想进一步概括它并获得一个几乎完美的别名std::get,你可以使用一个变量模板:

template<int N>
constexpr auto getFromPosition = [](auto &&t) constexpr -> decltype(auto) { return std::get<N>(std::forward<decltype(t)>(t)); };
Run Code Online (Sandbox Code Playgroud)

现在您可以调用它,如下所示:

S<getFromPosition<0>(t)> s{};
Run Code Online (Sandbox Code Playgroud)

wandbox上看到它.

  • 我们是否在某种以lambda为主导的天堂?什么是普通的旧功能? (3认同)