为什么std::function没有function_type或等效的成员类型?

4
这里看来,似乎std::function没有function_type或等效成员类型导出用于初始化它的实际类型。
它有result_typeargument_type以及first_argument_typesecond_argument_type,但没有像上面提到的类型。
为什么它不在其接口中提供这样的类型呢?
肯定有一个很好的原因,但我想不出是什么原因,所以我只是好奇想找出来。


我知道第一个问题会是你为什么需要它,好吧,想象一下我想做类似于std::is_same<F1 :: function_type,F2 :: function_type> :: value这样的事情,在 sfinae 评估中检查它们的底层类型是否相同,其中如果它们包含不同的函数而符号相同就可以了。
诚然,我承认这没什么意义,说实话这个问题只是出于好奇。

编辑

如@Brian在他的答案评论中所指出的那样,当我写:时,我错误地使用了初始化这个术语:

导出用于初始化它的实际类型

我感兴趣的确实是模板参数。
例如,对于一个std::function<void(S&, int)>(其中S是一个结构体),function_type将为void(S&, int)


1
对于is_same检查,你可以简单地检查F1F2是否是相同的类型,是吗? - Brian Bi
@Brian 是的,绝对没错,注意我的评论 我承认这没有多大意义!! :-) ... 我只是好奇是否有什么原因它不是函数接口的一部分,即使我找不到合理的用途,这已经是一个很好的回答了。我不确定 它是无用的 是否是唯一合理的回答,或者是否还有其他原因。就这些。 - skypjack
2个回答

6
我觉得你问错了问题。正确的问题应该是:为什么需要这样的成员类型?
比如说,如果你编写一个函数模板,可以接受 std::function 的任何特化,那么模板参数将立即对你可用:
template <typename T>
void f(std::function<T> F) {
    // you wouldn't write decltype(F)::function_type here; you'd just write T
}

更麻烦的情况是当你需要一些像这样的函数:
template <typename Callable>
void f(Callable C);

在这里,无法保证Callablestd::function的特化版本,因此,即使std::function<T>具有typedef T function_type,您也不希望为任意callable访问Callable::function_type。所以它在这里没有任何用处。
正确的问题是: 为什么一些标准库类会公开其模板参数,例如,T 的容器(其中有typedef T value_type)? 因为标准有一系列特定的要求,容器类型必须满足这些要求, 这反映了设计目标,即应该能够编写适用于不同类型的容器的通用算法,而不是所有这些类型都是C<T>的模板特化。因此,强制所有容器公开 value_type 是有意义的,因为这是从任意容器中提取元素类型的唯一统一方法。
如果std::function也是某个Callable概念的实例,那么有一个function_type typedef的要求就是有意义的,以便接受任何Callable的代码可以访问函数类型。但实际情况并非如此,并且仅对单个模板std::function拥有它是没有用处的。

3
您可以轻松地编写一个:
template < typename T >
struct function_type;

template < typename Sig >
struct function_type<std::function<Sig>> { using type = Sig; };

在术语上,您需要的单词是“实例化”。您正在寻找模板实例化时使用的类型。
唯一知道为什么它不是成员类型的人是那些设计该功能并投票通过的人(也许)。这可能只是没有人想到的事情。从想要它的角度来看,它似乎有点显而易见,但这是事后的观点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接