我想使用 SFINAE 检查特定命名空间中是否存在函数。我找到了 SFINAE to test a free function from another namespace哪个完成了工作,但有些事情我不明白。
目前我有这个工作代码,直接来自链接的问题:
// switch to 0 to test the other case
#define ENABLE_FOO_BAR 1
namespace foo {
#if ENABLE_FOO_BAR
int bar();
#endif
}
namespace detail_overload {
template<typename... Args> void bar(Args&&...);
}
namespace detail {
using namespace detail_overload;
using namespace foo;
template<typename T> decltype(bar()) test(T);
template<typename> void test(...);
}
static constexpr bool has_foo_bar = std::is_same<decltype(detail::test<int>(0)), int>::value;
static_assert(has_foo_bar == ENABLE_FOO_BAR, "something went wrong");
(ENABLE_FOO_BAR 宏仅用于测试目的,在我的实际代码中我没有这样的宏可用,否则我不会使用 SFINAE)
但是,一旦我将 detail_overload::bar() 放入任何其他命名空间(根据需要调整 using 指令),检测就会悄无声息地中断并且 static_assert 在foo::bar() 存在 时启动。它仅在“虚拟”bar() 重载直接位于全局命名空间或 ::detail_overload 命名空间的一部分时有效(注意全局 :: 范围)。
// breaks
namespace feature_test {
namespace detail_overload {
template<typename... Args> void bar(Args&&...);
}
namespace detail {
using namespace detail_overload;
using namespace foo;
//...
// breaks
namespace feature_test {
template<typename... Args> void bar(Args&&...);
namespace detail {
using namespace foo;
//...
// breaks
namespace detail {
namespace detail_overload {
template<typename... Args> void bar(Args&&...);
}
using namespace detail_overload;
using namespace foo;
//...
// works
template<typename... Args> void bar(Args&&...);
namespace feature_test {
namespace detail {
using namespace foo;
//...
// works
namespace detail_overload {
template<typename... Args> void bar(Args&&...);
}
namespace feature_test {
namespace detail {
using namespace detail_overload;
using namespace foo;
//...
我意识到这与我链接到的问题完全相同,并且如前所述,我已经有了一个可行的解决方案,但没有解决的是为什么恰好会发生这种情况?
作为附带问题,是否有任何方法可以在不使用 bar() 或 detail_overload 命名空间污染全局命名空间的情况下实现正确的 SFINAE 检测?您可以从非工作示例中猜到,我想将所有内容整齐地包装在一个 feature_test 命名空间中。
最佳答案
我会稍作更改,以便 bar 的回退声明不是模板(= 更短的代码),并且不要使用 SFINAE,因为这纯粹是一个名称查找问题。
namespace foo {
int bar(int);
}
namespace feature_test {
namespace detail_overload {
void bar(...);
}
namespace detail {
using namespace detail_overload;
using namespace foo;
void test() { bar(0); } // (A)
}
}
在 (A) 行中,编译器需要找到名称 bar。它是如何查找的?它不依赖于参数,因此它必须是非限定查找:[basic.lookup.unqual]/2
The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing the using-directive; see 7.3.4. For the purpose of the unqualified name lookup rules described in 3.4.1, the declarations from the namespace nominated by the using-directive are considered members of that enclosing namespace.
请注意它们成为封闭 命名空间,而不是the 封闭命名空间。来自 [namespace.udir]/2 的细节揭示了这个问题:
[...] During unqualified name lookup (3.4.1), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace.
也就是说,对于 test 中 bar 的名称查找:
namespace foo {
int bar(int);
}
// as if
using foo::bar;
namespace feature_test {
namespace detail_overload {
void bar(...);
}
// as if
using detail_overload::bar;
namespace detail {
// resolved
// using namespace detail_overload;
// using namespace foo;
void test() { bar(0); } // (A)
}
}
因此,在 feature_test 中找到的名称 bar 隐藏了在全局范围内(未)找到的名称。
注意:也许您可以通过依赖于参数的名称查找(和第二个 SFINAE)解决这个问题。如果我想到了什么,我会添加。
关于c++ - SFINAE:当重载移动到其他 namespace 时,检查函数是否存在中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18933857/
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我想在一个没有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)
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案