是否有等效的 #ifdef 来测试成员是否存在于类中,以便可以在不导致代码无法通过编译器的情况下完成处理。我尝试过模板操作,但特定问题没有成功。
例如
#if member baseclass.memberA()
baseclass.memberA().push_back(data);
#else
doAlternate(data);
#endif
// Instantiate an element of the Maindata class
::basedata::Maindata maindata;
//Instantiate an element of the Subdata class
::basedata::Subdata subinfo("This goes into the subinfo vector");
// Process some data that is part of the Subdata class
subinfo.contexts(contextInfo);
// Push the instantiated Subdata into the Subdata member of Maindata
maindata.subdata().push_back(subinfo);
最佳答案
这只是 void_t 的另一个案例.
我们需要一个小 helper 模板Void并定义一个方便的模板类型别名 void_t .
#include <type_traits>
template<typename...>
struct Void { using type = void; };
template<typename... T>
using void_t = typename Void<T...>::type;
template<typename T, typename = void>
struct Helper
{
static void
function(T& t)
{
std::cout << "doing something else with " << &t << std::endl;
}
};
.data().push_back(int) .template<typename T>
struct Helper<T, void_t<decltype(std::declval<T>().data().push_back(0))>>
{
static void
function(T& t)
{
std::cout << "pushing back data to " << &t << std::endl;
t.data().push_back(42);
}
};
Helper来自我们客户的实现细节并允许对模板参数进行类型推导,我们可以很好地包装它。template<typename T>
void
function(T& t)
{
Helper<T>::function(t);
}
#include <iostream>
#include <vector>
class Alpha
{
public:
std::vector<int>& data() { return this->data_; }
private:
std::vector<int> data_ {};
};
class Beta { /* has no data() */ };
int
main()
{
Alpha alpha {};
Beta beta {};
std::cout << "&alpha = " << &alpha << std::endl;
std::cout << "&beta = " << &beta << std::endl;
function(alpha);
function(beta);
}
&alpha = 0x7ffffd2a3eb0
&beta = 0x7ffffd2a3eaf
pushing back data to 0x7ffffd2a3eb0
doing something else with 0x7ffffd2a3eaf
frobnicate这需要一个泛型类型的参数,如果对象有...incr不带参数的,调用它,name , 如果可能的话,附加一些文本和 numbers , push_back如果可能的话,给它一些数字。 struct s 如上所示。它没有那么多多余的输入,并且可以使代码更清晰。void_t 的定义相同如上所示,我们可以定义如下宏。#define MAKE_SFINAE_HELPER(NAME, TYPE, OPERATION, ARGS, CODE) \
template<typename TYPE, typename = void> \
struct NAME \
{ \
template<typename... AnyT> \
void \
operator()(AnyT&&...) noexcept \
{ \
/* do nothing */ \
} \
}; \
\
template<typename TYPE> \
struct NAME<TYPE, void_t<decltype(std::declval<TypeT>()OPERATION)>> \
{ \
void operator()ARGS noexcept(noexcept(CODE)) \
{ \
CODE; \
} \
};
struct叫 NAME在类型参数上模板化 TYPE并使用运算符 () 定义主模板它接受任意数量的任何类型的参数并且绝对不执行任何操作。如果不支持所需的操作,这将用作后备。TYPE 的对象支持操作OPERATION ,然后是带有运算符 () 的偏特化接受参数 ARGS并执行 CODE将会被使用。宏定义为 ARGS可以是带括号的参数列表。不幸的是,预处理器语法只允许将单个表达式作为 CODE 传递。 .这不是一个大问题,因为我们总是可以编写一个委托(delegate)给另一个函数的函数调用。 (请记住,计算机科学中的任何问题都可以通过添加额外的间接级别来解决——当然,间接级别过多的问题除外……)运算符 ()将声明部分特化的 noexcept当且仅当 CODE是。 (这也仅适用于 CODE 仅限于单个表达式。)()的原因因为主模板是一个模板,否则编译器可能会发出有关未使用变量的警告。当然,您可以更改宏以接受附加参数 FALLBACK_CODE放置在主模板运算符的主体中 ()应该使用相同的 ARGS然后。OPERATION和 CODE参数为一个,然后 CODE不能引用ARGS这有效地限制了 ARGS到 TYPE 类型的单个参数在这种情况下,如果您不需要灵活性,您也可以去掉该参数。template<typename ObjT, typename NumT>
void
do_with_numbers(ObjT& obj, NumT num1, NumT num2, NumT num3)
{
obj.numbers.push_back(num1);
obj.numbers.push_back(num2);
obj.numbers.push_back(num3);
}
MAKE_SFINAE_HELPER(HelperIncr,
TypeT,
.incr(),
(TypeT& obj),
obj.incr())
MAKE_SFINAE_HELPER(HelperName,
TypeT,
.name += "",
(TypeT& obj, const std::string& appendix),
obj.name += appendix)
MAKE_SFINAE_HELPER(HelperNumbers,
TypeT,
.numbers.push_back(0),
(TypeT& obj, int i1, int i2, int i3),
do_with_numbers(obj, i1, i2, i3))
frobnicate功能。这真的很简单。template<typename T>
void
frobnicate(T& object)
{
HelperIncr<T>()(object);
HelperName<T>()(object, "def");
HelperNumbers<T>()(object, 4, 5, 6);
}
struct s 部分支持相关操作。#include <string>
#include <vector>
struct Widget
{
std::vector<int> numbers {1, 2, 3};
int counter {};
void incr() noexcept { this->counter += 1; }
};
struct Gadget
{
std::string name {"abc"};
int counter {};
void incr() noexcept { this->counter += 1; }
};
<< .#include <iostream>
std::ostream&
operator<<(std::ostream& os, const Widget& w)
{
os << "Widget : { counter : " << w.counter << ", numbers : [";
int i {};
for (const auto& v : w.numbers)
os << (i++ ? ", " : "") << v;
os << "] }";
return os;
}
std::ostream&
operator<<(std::ostream& os, const Gadget& g)
{
os << "Gadget : { counter : " << g.counter << ", "
<< "name = \"" << g.name << "\" }";
return os;
}
int
main()
{
Widget widget {};
Gadget gadget {};
std::cout << widget << "\n" << gadget << "\n\n";
frobnicate(widget);
frobnicate(gadget);
std::cout << widget << "\n" << gadget << "\n";
}
Widget : { counter : 0, numbers : [1, 2, 3] }
Gadget : { counter : 0, name = "abc" }
Widget : { counter : 1, numbers : [1, 2, 3, 4, 5, 6] }
Gadget : { counter : 1, name = "abcdef" }
关于C++ 预处理器测试类成员是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28748868/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我的瘦服务器配置了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
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test