为什么C ++ 20模板lambda使用typename关键字?

时间:2019-06-07 09:46:22

标签: c++ typename c++20 generic-lambda

我了解一致性参数,但是模板的大多数参数都是类型,因此我认为,由于lambda是用于定义结构的简洁方法,因此它可能应该默认为typename / {{1 }}(您仍然需要写class)。

如果有人不熟悉C ++ 20中对lambda的更改,请参见以下示例:

int/size_t/short

我的问题是为什么不这样做

[]<typename T>(const std::vector<T>& v)
{
    for(const auto& x : v) { std::cout << x; }
};

3 个答案:

答案 0 :(得分:7)

问题在于此已经具有含义:

template <T> void foo();

这是带有一个模板参数的功能模板,该模板参数是类型为T非类型模板参数,并且该模板参数没有名称。

如果要引入功能模板还是通用lambda,如果相同的语法意味着非常不同,这将非常令人困惑-也就是说,两个非常相似的上下文服务相似目的!

然后……如果您实际上想要一个非类型的模板参数,您将怎么办?只是不能拥有一个?

答案 1 :(得分:3)

虽然简洁确实是lambda的卖点,但它不足以取代对一致性的需求。对于涉及模板的功能尤其如此,因为它们比非模板语言的功能更难掌握。

尤其是,通用lambda的模板语法首先具有狭窄的范围,即,大多数lambda都可以在没有它的情况下生存(实际上,您给出的示例是不将其用作函数体的完美示例。不会实例化pubilc void setData(List newData){ this.list = newData } 或进行类似的操作)。来自P0428(重点是我):

  

作者认为当前用于定义通用lambda的语法不足的原因很少。要点是,某些可以使用常规功能模板轻松完成的事情需要使用通用lambda来完成,或者根本无法完成。

体内使用onPostExecute() { ... RecyclerView recyclerView = ((Activity) context).findViewById(R.id.recyclerViewAntamIncomingScanQR); BagLotNumberAdapter bagLotNumberAdapter = (BagLotNumberAdapter )recyclerView.getAdapter(); bagLotNumberAdapter.setData(bagLotNumbers); ((Activity) context).runOnUiThread(new Runnable() { @Override public void run() { // Update adapter bagLotNumberAdapter.notifyDataSetChanged(); } }); ... } 的通用lambda可能是新功能的最主要客户。就额外的打字和简洁性而言,用T代替decltype / decltype欺骗对我来说似乎更可接受。

答案 2 :(得分:2)

如果你只是写

[]<T>(){ }

T是什么?

typename? 一个auto值?

在我看来,在lambda中,就像在通用函数中一样,有必要明确说明什么是模板参数。

如果您可以从用途中推断出T是一种类型(如果它被用作std::vector的第一个模板参数,则必须是一种类型),为什么只简化lambda语法,而不要简化传统模板功能?