在 related question 中,据说没有指向非成员 const 函数的指针。另外,C++11 8.3.5/6 说
The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. [ Note: a function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types. —end note ]
如果我理解正确,这意味着不存在非成员 const 函数。 (虽然这些函数不是 const 的,但它们不能按照 3.10/6 进行修改)。尤其是指向 const 函数的指针是没有意义的。
但是,似乎某些编译器确实在类型推导上下文中创建了指向 const 函数的指针。例如,考虑以下代码:
#include <iostream>
void f() {}
template <typename T> void g( T*) { std::cout << "non const" << std::endl; }
template <typename T> void g(const T*) { std::cout << "const " << std::endl; }
int main() {
g(f);
}
当使用 GCC 和 Intel 编译时,代码输出“non const”,正如我从上面的引用中所期望的那样。但是,使用 Clang 和 Visual Studio 编译时,输出为“const”。
我的解释正确吗?
更新:
在评论之后,我试图澄清我不是在谈论 const 成员函数。我对非成员函数感兴趣(但同样的论点可能也适用于非静态成员函数)。我还更改了问题标题以使其更准确。
与上面提到的g(f)的分辨率一致,下面一行对于GCC和Intel是非法的,但对于Clang和Visual Studio是不合法的
const auto* ptr = &f;
更新 2:
我同意 Andy Prowl 的解释并选择了他的答案。但是,在那之后,我意识到这个问题是 CWG open issue 。
最佳答案
If I understand it correctly, this means that there's no such thing as a non-member const function. (Although such functions are not const, they cannot be modified as per 3.10/6). In particular, pointers to const function are meaningless.
是的,没有像 const 函数这样的东西,并且由于您引用的段落完全相同,因此忽略了创建一个函数的尝试。这一点很重要,因为无论如何创建 const 函数类型的程序都是not 格式错误的 (as was the case in C++03);简单地说,它的尝试被忽略,而是考虑一个非const函数类型。
这可能是 GCC 和 ICC 无法应用的原因,因为当非 const 重载被移除时,the program does not compile :
#include <iostream>
void f() {}
template <typename T> void g( T const*)
{
std::cout << "const " << std::endl;
}
int main() {
g(f); // ERROR with GCC and ICC, compiles with Clang
}
关于你的解释:
When compiled with GCC and Intel the code outputs "non const" as I would expect from the quote above. However, the output is "const" when compiled with Clang and Visual Studio. Is my interpretation correct?
我不相信。据我所知,Clang 是对的。
这个结论是基于两个函数模板都是可行的,因为 const 限定符在函数类型上被忽略,并且一个比另一个更专业。
事实上,根据 C++11 标准的第 8.3.5/7 段:
[...] The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. [...]
这有效地使第二个函数模板可用于解析调用(显然第一个是)。但是由于两个函数模板都是可行的,关于重载决议的第 13.3.3.1 段开始发挥作用:
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
— for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
— the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type. [ ... ] or, if not that,
— F1 is a non-template function and F2 is a function template specialization, or, if not that,
— F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.6.2.
由于第二个函数模板比第一个更专业,所以第二个函数模板应该由重载决议选择。因此,Clang 是对的。
关于c++ - "const T*"可以匹配指向自由函数的指针吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15578298/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
为了将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
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re