2016-04-25 55 views
0

在从this问题this答案提交张贴此代码:C++:关键字“类型名称”的在此函数中的含义

template <typename... Ts> 
    typename std::tuple_element<0, std::tuple<Ts...> >::type // or decltype(auto) 
     callFunction(Ts&&... ts) 
    { 
     using type = typename std::tuple_element<0, std::tuple<Ts...> >::type; 
     auto it = multiCache.find(typeid(type)); 
     assert(it != multiCache.end()); 
     auto&& fn = boost::any_cast<const std::function<type(Ts...)>&>(it->second); 
     return fn(std::forward<Ts>(ts)...); 
    } 

typename std::tuple_element<0, std::tuple<Ts...> >::type含义是,返回的类型相同的第一个元素的第一个元素在Ts...,对不对?

+1

是的,这是穷人的“索引到类型参数包”。这在这种情况下有点愚蠢,因为你可能只是写'T &&,Ts && ...'函数并直接使用'T'。 –

回答

0

不,typename关键字在所有实际用途上的含义与class相同。

这个差别有点语义。在模板函数或类的上下文中,typename也可以是POD,而不是正式声明的类。从字面上讲,它的意思是“任何类型,POD或一类”,宽泛地说。

这就是关键字typename的意思。在这种情况下,这具有一个特定的目的:

typename std::tuple_element<0, std::tuple<Ts...> >::type 

这告诉编译器期望在std::tuple_element<0, std::tuple<Ts...> >“类型”也将是class(或typedef),相对于一个类的成员。

当你有东西,看起来像:

classname::identifier 

这可以指一个类型或类成员:

class X { 

public: 
    typedef int y; 
    int z; 
}; 

这里,X::y是指一个类型,而X::z指一个班级成员。在解析模板时,C++编译器将默认假设“A :: b”将引用类成员,除非您在前面粘贴了一个typename,在这种情况下,它将被解析为类型。

+1

嗨,山姆。几个想法:当列出模板参数la'template '时,'typename'和'class'可以互换使用。 *“一个'typename''也可以是一个POD,而不是一个正式声明的类。”* - 在我之前的例子中,这同样适用于'A'和'B' - 编译器没有区分,但一些编码标准做。 *“,而不是类成员”*/*“将引用类成员”* - types /'typedef's可以是类成员 - 最好将它们与class * data *成员进行对比。 –