Dun*_*ter 5 c++ tuples c++-standard-library c++11
structs当将不同类型的值分组在一起时,通常会创建自定义。通常这很好,而且我个人觉得命名成员访问更容易阅读,但是我想创建一个更通用的API。在其他语言中广泛使用元组之后,我想返回type的值,std::tuple但是发现在C ++中使用它们比在其他语言中使用起来更加难看。
在使元素访问使用整数模板参数时,需要进行哪些工程决策get?
#include <iostream>
#include <tuple>
using namespace std;
int main()
{
auto t = make_tuple(1.0, "Two", 3);
cout << "(" << get<0>(t) << ", "
<< get<1>(t) << ", "
<< get<2>(t) << ")\n";
}
Run Code Online (Sandbox Code Playgroud)
而不是像下面这样简单的东西?
t.get(0)
Run Code Online (Sandbox Code Playgroud)
要么
get(t,0)
Run Code Online (Sandbox Code Playgroud)
有什么好处?我只看到其中的问题:
编辑:我已经接受了答案。现在,我已经考虑了语言需要知道的内容以及何时需要知道的内容,我认为这确实有意义。
max*_*x66 10
你说的第二个:
如果范围太大,它会使通过运行时生成的索引建立索引变得困难(例如,对于一个小的有限范围索引,我已经看到了使用每种可能性的switch语句编写的代码),或者无法进行索引。
C ++是一种高度静态的类型化语言,必须确定所涉及的类型编译时
所以一个功能
template <typename ... Ts>
auto foo (std::tuple<Ts...> const & t, std::size_t index)
{ return get(t, index); }
Run Code Online (Sandbox Code Playgroud)
是不可接受的,因为返回的类型取决于运行时值index。
采用的解决方案:将索引值作为编译时间值,作为模板参数。
如您所知,我想,它与a完全不同std::array:您有一个get()(方法at(),也有operator[])接收运行时索引值:std::array值类型并不取决于索引。
需要模板参数的“工程决策”std::get<N>比您想象的要深得多。您正在研究静态类型系统和动态类型系统之间的区别。我建议阅读https://en.wikipedia.org/wiki/Type_system,但这里有一些要点:
在静态类型中,变量/表达式的类型必须在编译时已知。get(int)在这种情况下, 的方法不能std::tuple<int, std::string>存在,因为 的参数get在编译时无法得知。另一方面,由于模板参数必须在编译时已知,因此在这种情况下使用它们是非常有意义的。
C++ 也具有多态类形式的动态类型。这些利用运行时类型信息(RTTI),这会带来性能开销。的正常用例std::tuple不需要动态类型,因此它不允许这样做,但 C++ 为这种情况提供了其他工具。
例如,虽然您不能拥有std::vector包含 和 混合的inta std::string,但您完全可以拥有包含 an和包含 a 的std::vector<Widget*>where ,只要两者都派生自。鉴于,说,IntWidgetintStringWidgetstd::stringWidget
struct Widget {
virtual ~Widget();
virtual void print();
};
Run Code Online (Sandbox Code Playgroud)
您可以调用print向量的每个元素,而无需知道其确切(动态)类型。