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 argumentTTor a template non-type argumentican be deduced ifPandAhave one of the following forms:
T cv-list T T* 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 aniand<>represents template argument lists where no argument contains aTor 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/
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option