什么是非演绎上下文? [英] What is a nondeduced context?

查看:34
本文介绍了什么是非演绎上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶然发现了为什么是模板参数推导在这里不起作用?"最近,答案可以总结为这是一个非推导的上下文".

I've stumbled over "Why is the template argument deduction not working here?" recently and the answers can be summed up to "It's a nondeduced context".

具体来说,第一个说它是这样的,然后重定向到细节"标准,而第二个引用标准,至少可以说是神秘的.

Specifically, the first one says it's such a thing and then redirects to the standard for "details", while the second one quotes the standard, which is cryptic to say the least.

有人可以向像我这样的凡人解释一下什么是非推断上下文,它何时发生,为什么会发生?

Can someone please explain to mere mortals, like myself, what a nondeduced context is, when does it occur, and why does it occur?

推荐答案

推导 是指从给定参数中确定模板参数类型的过程.它适用于函数模板、auto 和其他一些情况(例如部分特化).例如,考虑:

Deduction refers to the process of determining the type of a template parameter from a given argument. It applies to function templates, auto, and a few other cases (e.g. partial specialization). For example, consider:

template <typename T> void f(std::vector<T>);

现在如果你说f(x),你声明了std::vectorx;,然后T推导出int,你得到特化f.

Now if you say f(x), where you declared std::vector<int> x;, then T is deduced as int, and you get the specialization f<int>.

为了使推导起作用,要推导的模板参数类型必须出现在可推导的上下文中.在这个例子中,f 的函数参数就是这样一个可推导的上下文.也就是说,函数调用表达式中的参数允许我们确定模板参数 T 应该是什么,以便调用表达式有效.

In order for deduction to work, the template parameter type that is to be deduced has to appear in a deducible context. In this example, the function parameter of f is such a deducible context. That is, an argument in the function call expression allows us to determine what the template parameter T should be in order for the call expression to be valid.

然而,也有推导的上下文,其中无法推导.规范示例是出现在 :::

However, there are also non-deduced contexts, where no deduction is possible. The canonical example is "a template parameter that appears to the left of a :::

template <typename> struct Foo;

template <typename T> void g(typename Foo<T>::type);

在这个函数模板中,函数参数列表中的T是在一个非推导的上下文中.因此你不能说 g(x) 并推导出 T.这样做的原因是任意类型和成员 Foo::type 之间没有反向对应".例如,您可以拥有专长:

In this function template, the T in the function parameter list is in a non-deduced context. Thus you cannot say g(x) and deduce T. The reason for this is that there is no "backwards correspondence" between arbitrary types and members Foo<T>::type. For example, you could have specializations:

 template <> struct Foo<int>       { using type = double; };
 template <> struct Foo<char>      { using type = double; };
 template <> struct Foo<float>     { using type = bool; };
 template <> struct Foo<long>      { int type = 10; };
 template <> struct Foo<unsigned>  { };

如果你调用 g(double{})T 有两种可能的答案,如果你调用 g(int{})> 没有答案.一般来说,类模板参数和类成员之间没有关系,所以你不能进行任何合理的参数推导.

If you call g(double{}) there are two possible answers for T, and if you call g(int{}) there is no answer. In general, there is no relationship between class template parameters and class members, so you cannot perform any sensible argument deduction.

有时明确禁止参数推导很有用.例如,std::forward 就是这种情况.另一个例子是当你有从 FooFoo 的转换,或者其他转换(想想 std::stringchar const *).现在假设您有一个免费功能:

Occasionally it is useful to inhibit argument deduction explicitly. This is for example the case for std::forward. Another example is when you have conversions from Foo<U> to Foo<T>, say, or other conversions (think std::string and char const *). Now suppose you have a free function:

template <typename T> bool binary_function(Foo<T> lhs, Foo<T> rhs);

如果调用binary_function(t, u),则推导可能不明确,从而失败.但是只推导出一个参数而推导出另一个是合理的,因此允许隐式转换.现在需要一个明确的非推导上下文,例如这样:

If you call binary_function(t, u), then the deduction may be ambiguous and thus fail. But it is reasonable to deduce only one argument and not deduce the other, thus permitting implicit conversions. Now an explicitly non-deduced context is needed, for example like this:

template <typename T>
struct type_identity {
    using type = T;
};

template <typename T>
bool binary_function(Foo<T> lhs, typename type_identity<Foo<T>>::type rhs)
{
    return binary_function(lhs, rhs);
}

(您可能遇到过类似 std::min(1U, 2L) 之类的推导问题.)

(You may have experienced such deduction problems with something like std::min(1U, 2L).)

这篇关于什么是非演绎上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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