有没有人看过Andrei Alexandrescu在GoingNative2013中关于爆炸元组的讨论呢?
以下是我不太关注的代码:
template <class F, class... Ts>
auto explode(F&& f, const tuple<Ts...>& t)
-> typename result_of<F(Ts...)>::type
{
return Expander<sizeof...(Ts),
typename result_of<F(Ts...)>::type,
F,
const tuple<Ts...>&>::expand(f, t);
}
结果中的F(Ts ...)让我很烦恼。我的意思是:F不代表功能类型吗? 我知道R(Ts ......)很好,但这里的R是一个返回类型,但是在R应该使用F的地方,这就是让我疯狂的事情......
有人能帮我理解奇怪的F(Ts ......)吗?
以下是Andrei Alexandrescu演讲的链接: http://channel9.msdn.com/Events/GoingNative/2013/The-Way-of-the-Exploding-Tuple
答案 0 :(得分:1)
您想问的问题可能与此问题重复:Why does std::result_of take an (unrelated) function type as a type argument?
让我们剖析:
std::result_of<F(Ts...)>::type
所以,在namespace std
的某个地方,我们有一个类模板result_of<>
。它需要一个模板类型参数;即它看起来基本上是这样的:
template<typename Foo>
struct result_of
{
typedef FOOBARBAZ type;
};
好的,我们正在使用参数F(Ts...)
实例化此模板。这是不寻常的语法!您可能知道Ts
是参数包,因此括号内的Ts...
将在编译时扩展为以逗号分隔的类型列表,例如int, double, bool
。所以我们得到F(int, double, bool)
。好的,这是一种功能类型。
正如int(char)
表示“功能正常char
并返回int
”一样,F(int, double, bool)
也表示“功能正常int, double, bool
并返回{{1} }”。
“但等等,”你说。 “我以为F
已经是我的功能类型!”
是。 F
是 您的 功能类型。但F
所期望的类型是,真的!,该函数类型包含在另一个函数类型中。详细说明:
std::result_of
以上每一行都完全等效:typedef int (*F)(char);
typedef F G(char);
static_assert(std::is_same< std::result_of<G>::type, int >::value);
static_assert(std::is_same< std::result_of<F(char)>::type, int >::value);
static_assert(std::is_same< std::result_of<int (*(char))(char)>::type, int >::value);
只是一种更美观的写作方式F(char)
。当然,你不能总是逃脱它,因为有时int (*(char))(char)
是一个无法从函数返回的函数类型:
F
正如@Simple在评论中所写,typedef int F(char);
std::result_of<F(char)>; // fails to compile
总是可以用不那么聪明但也不那么混乱的表达来代替
std::result_of<F(Ts...)>::type
即“使用decltype( std::declval<F>() ( std::declval<Ts>()... ) )
类型的参数调用类型decltype
的值的结果的F
。这里,没有古怪的高级函数类型;一切都只是按照你自然期望的方式工作。就我个人而言,我可能会在我自己的代码中使用Ts...
方法,因为它更容易理解;但我想有些人会更喜欢decltype
方法,因为它看起来表面上更简单,并且受到标准的祝福。对于他自己的每一个。:)