什么时候类型信息在C ++中向后流动? [英] When does type information flow backwards in C++?

查看:81
本文介绍了什么时候类型信息在C ++中向后流动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚在CppCon 2018在类模板参数推论"上观看了斯蒂芬·拉瓦维(Stephan T. Lavavej)的演讲,其中在

I just watched Stephan T. Lavavej talk at CppCon 2018 on "Class Template Argument Deduction", where at some point he incidentally says:

在C ++类型的信息中,信息几乎永远不会倒退... 我不得不说几乎"是因为存在一两种情况,可能更多但很少.

In C++ type information almost never flows backwards ... I had to say "almost" because there's one or two cases, possibly more but very few.

尽管试图弄清楚他可能指的是哪种情况,但我什么也没想出来.因此,问题是:

Despite trying to figure out which cases he might be referring to, I couldn't come up with anything. Hence the question:

在哪种情况下,C ++ 17标准要求类型信息向后传播?

推荐答案

至少有一种情况:

struct foo {
  template<class T>
  operator T() const {
    std::cout << sizeof(T) << "\n";
    return {};
  }
};

如果您执行foo f; int x = f; double y = f;,则类型信息将向后流动"以查明operator T中的T.

if you do foo f; int x = f; double y = f;, type information will flow "backwards" to figure out what T is in operator T.

您可以以更高级的方式使用它:

You can use this in a more advanced way:

template<class T>
struct tag_t {using type=T;};

template<class F>
struct deduce_return_t {
  F f;
  template<class T>
  operator T()&&{ return std::forward<F>(f)(tag_t<T>{}); }
};
template<class F>
deduce_return_t(F&&)->deduce_return_t<F>;

template<class...Args>
auto construct_from( Args&&... args ) {
  return deduce_return_t{ [&](auto ret){
    using R=typename decltype(ret)::type;
    return R{ std::forward<Args>(args)... };
  }};
}

所以我现在可以做

std::vector<int> v = construct_from( 1, 2, 3 );

它有效.

当然,为什么不只是{1,2,3}呢?好吧,{1,2,3}不是表达式.

Of course, why not just do {1,2,3}? Well, {1,2,3} isn't an expression.

std::vector<std::vector<int>> v;
v.emplace_back( construct_from(1,2,3) );

当然,这需要更多的巫术:在线示例. (我必须让ducuce return对F进行SFINAE检查,然后使F对SFINAE友好,并且我必须在deduce_return_t运算符T中阻止std :: initializer_list.)

which, admittedly, require a bit more wizardry: Live example. (I have to make the deduce return do a SFINAE check of F, then make the F be SFINAE friendly, and I have to block std::initializer_list in deduce_return_t operator T.)

这篇关于什么时候类型信息在C ++中向后流动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆