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上看到它.