有没有办法使用 detection idiom (或其他方法)测试一个函数是否对给定的模板参数有效,如果它由于 static_assert?
下面的示例说明了 foo 的有效性(失败的返回类型计算)按预期被检测到,但是 bar 的有效性(失败的 static_assert ) 不是。
#include <iostream>
#include <type_traits>
template <typename... T> using void_t = void;
template <class AlwaysVoid, template<class...> class Op, class... Args>
struct detector: std::false_type { };
template <template<class...> class Op, class... Args>
struct detector<void_t<Op<Args...>>, Op, Args...>: std::true_type { };
template <template<class...> class Op, class... Args>
constexpr bool is_detected = detector<void, Op, Args...>::value;
template <typename T>
std::enable_if_t<!std::is_void<T>::value> foo() {
std::cout << "foo" << std::endl;
}
template <typename T>
void bar() {
static_assert( !std::is_void<T>::value );
std::cout << "bar" << std::endl;
}
template <typename T> using foo_t = decltype(foo<T>());
template <typename T> using bar_t = decltype(bar<T>());
int main(int argc, char* argv[]) {
foo<int>();
// foo<void>(); // fails as expected
bar<int>();
// bar<void>(); // fails as expected
std::cout << std::boolalpha;
// detection works for foo
std::cout << is_detected<foo_t,int > << std::endl; // true
std::cout << is_detected<foo_t,void> << std::endl; // false
// but not for bar
std::cout << is_detected<bar_t,int > << std::endl; // true
std::cout << is_detected<bar_t,void> << std::endl; // true !!!
}
这就是我无法检测 boost::lexical_cast 是否对给定类型有效的原因。
最佳答案
这里不可能使用 SFINAE 获得正确的输出,因为 SFINAE rules操作声明,而不是定义。
bar 的类型声明的永远是void(void) , 所以就 SFINAE 而言,声明是可以的。
如果你写了一个真正的检测习惯用法(比如 I did here ),并像这样使用它:
template <typename T>
using CanCallFoo_t = decltype(&foo<T>);
template<class T>
using CanCallFoo = detect<T, CanCallFoo_t, void>;
template<class T>
using CanCallBar_t = decltype(&bar<T>);
template< class T>
using
CanCallBar = detect<T, CanCallBar_t, void>;
//...
std::cout << CanCallFoo<int>::value << std::endl; // true
std::cout << CanCallFoo<void>::value << std::endl; // false
std::cout << CanCallBar<int>::value << std::endl;
std::cout << CanCallBar<void>::value << std::endl;
您会注意到 SFINAE 成功,然后在解析定义时出现编译器错误。
error: static assertion failed
static_assert( !std::is_void<T>::value );
请注意它适用于 foo因为foo的声明类型将因 void 的 SFINAE 失败
点static_assert是在没有找到其他更好匹配的情况下使编译失败,而不是作为 SFINAE 的替代品。
关于c++ - 检测带有函数失败 static_assert 的成语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45807904/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf