我有多个类(这里为简单起见 Foo 和 Bar)
struct Bar {};
struct Foo {};
和一个接受单个模板参数并根据该类型执行某些操作的函数:
template <typename T>
constexpr void doSomething() { cout << "Am I a Foo? " << is_same<T,Foo>::value << endl; }
在我的代码中,我得到了 Foo 的模板参数包s 和 Bar s,我应该调用 doSomething()每个函数都有函数(我不关心函数执行的顺序)。
doStuff<Foo, Bar, Bar>(); // --> True / False / False
到目前为止,我能想到的唯一解决方案是:
template <typename... Ts>
class Doer;
template <>
struct Doer <> {
static constexpr void doStuff() {}
};
template <typename Head, typename... Tail>
struct Doer <Head, Tail...> {
static constexpr void doStuff() {
doSomething<Head>();
Doer<Tail...>::doStuff();
}
};
template <typename... Ts>
constexpr void doStuff() {
return Doer<Ts...>::doStuff();
}
doStuff<Foo, Bar, Bar>(); // --> True / False / False
它有效,但我发现它相当困惑。我不得不使用具有部分特化的类模板,因为函数模板只支持完全特化。我也试过了
constexpr void doStuff() { }
template <typename Head, typename... Tail>
constexpr void doStuff() {
doSomething<Head>();
doStuff<Tail...>(); // --> Compile Error
}
但是编译器失败了,因为它无法计算出 doStuff<>()实际上是 doStuff() .如果我在我的可变参数函数中有参数,那么编译器足够聪明来解决这个冲突,因为它应用模板类型推导:
constexpr void doStuff() { }
template <typename Head, typename... Tail>
constexpr void doStuff(Head arg, Tail... args) {
doSomething<Head>();
doStuff(args...);
}
Foo f1;
Bar b1, b2;
doStuff<Foo, Bar, Bar>(f1, b1, b2); // --> True / False / False
我错过了什么吗?有没有一种方法可以在不使用函数参数或类模板的情况下使可变参数函数正常工作?
最佳答案
but the compiler fails because it can't figure out that doStuff<>() is actually doStuff().
怎么样
template <int = 0>
constexpr void doStuff() { }
template <typename Head, typename... Tail>
constexpr void doStuff() {
doSomething<Head>();
doStuff<Tail...>();
}
?
我的意思是:如果问题在于,最后模板可变参数列表是空的,请使用模板参数(完全不同:整数而不是类型)将模板版本中的基本情况转换为默认值。
所以,当Tail...为空,调用doStuff<Tail...>() , 即 doStuff<>() , 匹配doStuff<0>() (考虑到第一个函数中的默认值)所以调用基本情况。
无论如何:如果你可以使用 C++17,你就可以避免递归,并且使用逗号运算符和模板折叠的强大功能,你可以简单地编写
template <typename... Ts>
constexpr void doStuff() {
(doSomething<Ts>(), ...);
}
在C++14中你可以像下面这样模拟模板折叠
template <typename... Ts>
constexpr void doStuff() {
using unused = int[];
(void) unused { 0, ((void)doSomething<Ts>(), 0)... };
}
前面的解决方案也适用于 C++11,但不适用于 constexpr (而且 doSomething() 在 C++11 中不能是 constexpr)。
考虑到您不关心函数的执行顺序,我提出了一个维护 constexpr 的 C++11 解决方案。它基于假函数调用中的模板包扩展(或者可能不是假的......再见)。
但这需要 doSomething()是constexpr (所以,在 C++11 中,不能是 void )和 doStuff()不可能是void
#include <iostream>
template <typename T>
constexpr std::size_t doSomething ()
{ return sizeof(T); }
template <typename ... Ts>
constexpr int fakeFunc (Ts const & ...)
{ return 0; }
template <typename ... Ts>
constexpr int doStuff ()
{ return fakeFunc( doSomething<Ts>()... ); }
int main()
{
constexpr int a { doStuff<char, short, int, long, long long>() };
(void)a;
}
关于没有参数的 C++ 可变参数函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56451050/
我好像记得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
我有一些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
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了