gpt4 book ai didi

c++ - 什么是非推论上下文?

转载 作者:行者123 更新时间:2023-12-02 10:32:28 25 4
gpt4 key购买 nike

我最近偶然发现了“Why is the template argument deduction not working here?”,答案可以总结为“这是一个非推论上下文”。

具体来说,第一个引用这样的东西,然后重定向到“细节”的标准,而第二个引用该标准,至少可以这样说。

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

最佳答案

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

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

现在,如果您在声明 f(x)的地方说了 std::vector<int> x;,那么 T被推导为 int,并且得到了特化的 f<int>

为了使推导起作用,要推导的模板参数类型必须出现在可推导的上下文中。在此示例中, f的功能参数就是这种可推论的上下文。也就是说,函数调用表达式中的参数使我们能够确定模板参数 T应该是什么才能使调用表达式有效。

但是,也有非推论上下文,其中不可能进行推论。规范示例是“出现在 ::左侧的模板参数:
template <typename> struct Foo;

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

在此功能模板中,功能参数列表中的 T在非推导上下文中。因此,您不能说 g(x)并推断 T。这样做的原因是,任意类型和成员 Foo<T>::type之间没有“向后对应”。例如,您可能有专长:
 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{})则没有答案。通常,类模板参数和类成员之间没有关系,因此您无法执行任何明智的参数推导。

有时,明确禁止论证推论很有用。例如 std::forward就是这种情况。另一个示例是当您从 Foo<U>转换为 Foo<T>或其他转换(例如 std::stringchar const *)时。现在假设您有一个免费功能:
template <typename T> bool binary_function(Foo<T> lhs, Foo<T> rhs);

如果调用 binary_function(t, u),则推论可能会模棱两可,从而失败。但是,只推导一个参数而不推导另一个参数是合理的,因此允许隐式转换。现在需要一个明确的非推导上下文,例如:
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)这样的推论问题。)

关于c++ - 什么是非推论上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61752858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com