- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
C++允许非类型模板参数为指针,包括函数指针、类型。我最近问了一个question关于这有什么用,这是对 one of the answers 的跟进.
是否可以从作为相关函数指针的函数参数中推断出函数指针模板参数的值?例如:
using VoidFunction = void(*)();
template <VoidFunction F>
void templ(VoidFunction);
...
void func(); // a VoidFunction
...
templ<func>(func); // works, but I have to specify the template parameter explicitly
templ(func); // <-- I would like to be able to do this
有没有办法让这种扣除发生?从编译器实现者的角度来看,这在技术上似乎是可行的,只要函数参数可以在编译时解析为代码中的函数。
如果您想知道这背后的动机,请参阅 this answer 下的评论,特别是可能优化 std::bind()
的实现.
编辑:我意识到我可以简单地删除函数参数并使用模板参数,如 templ<func>()
.我添加函数参数的唯一目的是尽量避免必须传递模板参数。
我想我真正想要的是也推断出函数指针的类型,如:
template <typename Function, Function F>
void templ(/* something */);
然后可以调用
templ(func);
或
templ<func>();
并从函数指针的单次提及中推导出类型和值。
希望现在更有意义。
最佳答案
函数的模板参数是从函数模板参数的类型中推导出来的。当类型是允许的形式之一时,模板参数只能从类型中推导出来。允许的形式在 [temp.deduct.type] 中指定
Template arguments can be deduced in several different contexts, but in each case a type that is specified in terms of template parameters (call it
P
) is compared with an actual type (call itA
), and an attempt is made to find template argument values (a type for a type parameter, a value for a non-type parameter, or a template for a template parameter) that will makeP
, after substitution of the deduced values (call it the deducedA
), compatible withA
.A template type argument
T
, a template template argumentTT
or a template non-type argumenti
can be deduced ifP
andA
have one of the following forms:
Tcv-list TT*T&T[integer-constant]template-name (where template-name refers to a class template)type(*)(T)T(*)()T(*)(T)T type::*type T::*T T::*T (type::*)()type (T::*)()type (type::*)(T)type (T::*)(T)T (type::*)(T)T (T::*)()T (T::*)(T)type[i]template-name<i> (where template-name refers to a class template)TT<T>TT<i>TT<>
where
(T)
represents argument lists where at least one argument type contains aT
, and()
represents argument lists where no parameter contains aT
. Similarly,<T>
represents template argument lists where at least one argument contains aT
,<i>
represents template argument lists where at least one argument contains ani
and<>
represents template argument lists where no argument contains aT
or ani
.
When considering only non-type template arguments, the relevant forms are those that contain i
:
type[i]template-name<i> (where template-name refers to a class template)TT<i>
Therefore it is not possible to deduce the value directly from the value of a function argument that is the function pointer. However it is possible to deduce the value of a non-type template argument if the function parameter has one of the specified forms.
The following code ahieves this by wrapping the non-type template argument value in a class-template called NonType
. The parameter of f
is in the form template-name<i>
, making it possible for the value of its non-type template argument to be deduced.
template<typename T, T value>
struct NonType {};
template<typename T, T value>
void f(NonType<T, value>)
{
}
void g();
struct A
{
void f();
int m;
};
int i;
#define MAKE_NONTYPE(value) NonType<decltype(value), (value)>()
int main()
{
f(MAKE_NONTYPE(0)); // NonType<int, 0>
f(MAKE_NONTYPE(&g)); // NonType<void(*)(), &g>
f(MAKE_NONTYPE(&A::f)); // NonType<void(A::*)(), &A::f>
f(MAKE_NONTYPE(&A::m)); // NonType<int A::*, &A::m>
f(MAKE_NONTYPE(&i)); // NonType<int*, &i>
}
请注意,decltype
和 MAKE_NON_TYPE
宏在这里的使用只是为了方便起见,以避免必须写出 NonType
关于c++ - 有没有办法推断函数指针模板参数的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17736337/
我是一名优秀的程序员,十分优秀!