为什么 std::function 没有 function_type 或等效的成员类型?
Why std::function has no function_type or equivalent member type?
从 here 看来,std::function
没有 function_type
或等效的成员类型来导出用于初始化它的实际类型。
它有 result_type
、argument_type
,还有 first_argument_type
和 second_argument_type
,但与上面提到的类型完全不同。
为什么它不提供这种类型作为其接口的一部分?
肯定会有一个很好的理由,但我不知道那是什么原因,所以我很想知道。
因为我知道第一个问题是 为什么需要它,好吧,假设我想做类似 std::is_same<F1::function_type, F2::function_type>::value
的事情来检查它们的底层类型在sfinae评估中是相同的,只要符号相同,它们包含不同的功能就可以了。
我承认没有多大意义,说实话这个问题只是出于好奇
编辑
正如@Brian 在 his answer 的评论中指出的那样,我在写 initialize 时误用了术语:
to export the actual type used to initialize it
我真正感兴趣的是模板参数。
例如,对于 std::function<void(S&, int)>
(其中 S
是一个结构),function_type
将是 void(S&, int)
.
我认为你问错了问题。正确的问题是:为什么要有这样的会员类型?
比方说,如果您编写的函数模板可以接受 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);
这里,你不能保证 Callable
是 std::function
特化,所以即使 std::function<T>
有 typedef T function_type
,你也不想访问 Callable::function_type
用于任意可调用对象。所以在这里用不上。
正确的问题是:为什么一些标准库 类 公开它们的模板参数,例如 T
的容器(其中有 typedef T value_type
)?答案是该标准有一组容器类型必须满足的特定要求,这反映了一个设计目标,即应该可以编写适用于不同类型容器的通用算法,而不是所有容器都是模板特化形式 C<T>
。然后强制所有容器公开 value_type
是有意义的,因为这是从任意容器中提取元素类型的唯一统一方法。
如果 std::function
也是某个 Callable
概念的一个实例,那么要求有一个 function_type
typedef 以便代码接受任何 Callable
可以访问函数类型。但事实并非如此,仅对单个模板使用它没有用 std::function
.
你可以轻松写一个:
template < typename T >
struct function_type;
template < typename Sig >
struct function_type<std::function<Sig>> { using type = Sig; };
根据您的术语:instantiate 是您要找的词。您正在寻找模板 实例化 的类型。
唯一知道为什么它不是成员类型的人是设计该功能的人和(也许)投票的人。这可能只是没人想到的事情。确实看起来有点明显,但从想要的角度来看,这是事后诸葛亮。
从 here 看来,std::function
没有 function_type
或等效的成员类型来导出用于初始化它的实际类型。
它有 result_type
、argument_type
,还有 first_argument_type
和 second_argument_type
,但与上面提到的类型完全不同。
为什么它不提供这种类型作为其接口的一部分?
肯定会有一个很好的理由,但我不知道那是什么原因,所以我很想知道。
因为我知道第一个问题是 为什么需要它,好吧,假设我想做类似 std::is_same<F1::function_type, F2::function_type>::value
的事情来检查它们的底层类型在sfinae评估中是相同的,只要符号相同,它们包含不同的功能就可以了。
我承认没有多大意义,说实话这个问题只是出于好奇
编辑
正如@Brian 在 his answer 的评论中指出的那样,我在写 initialize 时误用了术语:
to export the actual type used to initialize it
我真正感兴趣的是模板参数。
例如,对于 std::function<void(S&, int)>
(其中 S
是一个结构),function_type
将是 void(S&, int)
.
我认为你问错了问题。正确的问题是:为什么要有这样的会员类型?
比方说,如果您编写的函数模板可以接受 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);
这里,你不能保证 Callable
是 std::function
特化,所以即使 std::function<T>
有 typedef T function_type
,你也不想访问 Callable::function_type
用于任意可调用对象。所以在这里用不上。
正确的问题是:为什么一些标准库 类 公开它们的模板参数,例如 T
的容器(其中有 typedef T value_type
)?答案是该标准有一组容器类型必须满足的特定要求,这反映了一个设计目标,即应该可以编写适用于不同类型容器的通用算法,而不是所有容器都是模板特化形式 C<T>
。然后强制所有容器公开 value_type
是有意义的,因为这是从任意容器中提取元素类型的唯一统一方法。
如果 std::function
也是某个 Callable
概念的一个实例,那么要求有一个 function_type
typedef 以便代码接受任何 Callable
可以访问函数类型。但事实并非如此,仅对单个模板使用它没有用 std::function
.
你可以轻松写一个:
template < typename T >
struct function_type;
template < typename Sig >
struct function_type<std::function<Sig>> { using type = Sig; };
根据您的术语:instantiate 是您要找的词。您正在寻找模板 实例化 的类型。
唯一知道为什么它不是成员类型的人是设计该功能的人和(也许)投票的人。这可能只是没人想到的事情。确实看起来有点明显,但从想要的角度来看,这是事后诸葛亮。