看完How to make these std::function parameters unambiguous?这个问题我完全糊涂了,到目前为止,我以为我理解什么是函数模板的部分排序,但是在阅读了那个问题之后,我写下了三个示例来检查编译器的行为,但收到的结果对我来说很难理解.
template <class T>
void foo(T) {}
template <class T>
void foo(T&) {}
int main()
{
int i;
foo<int>(i); // error: call is ambiguous!
}
问题:这两个函数都是可行的,这很明显,但不是那个占用 T& 的函数吗?比T更专业?相反,编译器会引发模棱两可的调用错误。
#include <iostream>
template <class T>
struct X {};
template <>
struct X<int>
{
X() {}
X(X<int&> const&) {} // X<int> is constructible from X<int&>
// note: this is not a copy constructor!
};
template <>
struct X<int&>
{
X() {}
X(X<int> const&) {} // X<int&> is constructible from X<int>
// note: this is not a copy constructor!
};
template <class T>
void bar(X<T>) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
template <class T>
void bar(X<T&>) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
int main()
{
bar<int>(X<int>()); // calls void bar(X<T>) [with T = int]
bar<int>(X<int&>()); // calls void bar(X<T&>) [with T = int]
}
问题:如果 T&和 T在示例 #1 中是模棱两可的,那么为什么这里没有调用是模棱两可的? X<int>可从 X<int&> 构建,以及 X<int&>可从 X<int> 构建感谢提供的构造函数。是不是因为编译器生成了X<int>::X(X<int> const&)复制构造函数是一个比X<int>::X(X<int&> const&) 更好的转换序列 ,(如果是这样,是什么让它变得更好,请注意参数是按值传递的),所以特化的顺序根本不重要?
#include <iostream>
// note: a new type used in constructors!
template <class U>
struct F {};
template <class T>
struct X
{
X() {}
template <class U>
X(F<U> const&) {} // X<T> is constructible from any F<U>
// note: it takes F type, not X!
};
template <class T>
void qux(X<T>) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
template <class T>
void qux(X<T&>) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
int main()
{
qux<int>(F<int>()); // calls void qux(X<T&>) [with T = int]
qux<int>(F<int&>()); // calls void qux(X<T&>) [with T = int]
}
问题:现在这与“匹配 lambda [](int){} 与 std::function<void(int&)> 和 std::function<void(int)>” 类似。为什么在这两个调用中都选择了更专业的函数模板?是不是因为转换顺序相同,所以偏序开始重要了?
所有测试在 GCC 4.9.0 上完成 -std=c++11并且没有额外的标志。
最佳答案
重载解析试图找到这样的最佳函数:
(1) [over.match.best]/1:
Given these definitions, a viable function
F1is defined to be a better function than another viable functionF2if for all arguments i,ICSi(F1)is not a worse conversion sequence thanICSi(F2), and then
— for some argument j,ICSj(F1)is a better conversion sequence thanICSj(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 ofF1to 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 ofF2to the destination type.
[ Example:struct A { A(); operator int(); operator double(); } a; int i = a; // a.operator int() followed by no conversion is better // than `a.operator double()` // followed by a conversion to `int` float x = a; // ambiguous: both possibilities require conversions, // and neither is better than the other— end example ] 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.
but isn't the one taking
T&more specialized thanT?
根据重载决议,没有转换更好(都是恒等转换,是精确匹配),并且由于(1)中没有其他项目适用,因此进行了部分排序。 [temp.deduct.partial]/5 表示为了部分排序,引用被它们引用的类型替换:
Before the partial ordering is done, certain transformations are performed on the types used for partial ordering:
— IfPis a reference type,Pis replaced by the type referred to.
— IfAis a reference type,Ais replaced by the type referred to.
由于参数模板的参数完全相同,因此不难看出相互推导都是成功的——因此两个模板都不比另一个更专业。
这里不需要部分排序。来自 X<int> 的用户定义转换至 X<int&>排名比转换 X<int> 差至 X<int> -- 后者由 [over.ics.user]/4 赋予完全匹配等级:
A conversion of an expression of class type to the same class type is given Exact Match rank, […]
因此它显然是比 X<int> 更好的转换至 X<int&> ,具有转化排名。反之亦然,对于 X<int&>至 X<int> .
第三种情况与第一种类似。 X<int>和 X<int&>两者都有一个构造函数模板,可以采用 F 的任意特化。 . (1) 告诉我们,由于没有一个转换序列在任何方面都优于另一个(事实上,它们完全相同),因此选择了更专业的模板。
template <class T> void bar(X<T>); // #1
template <class T> void bar(X<T&>); // #2
// Call:
bar<int>( F<int>() );
回到[temp.deduct.partial],执行类型推导。一个独特的类型,称之为Unique , 被合成为每个参数模板的模板参数。执行以下具有相应结果的过程 - 请注意,使用 F<int> 调用时,步骤完全相同与 F<int&> 一样(以及 F 的任何其他特化):
X<Unique&>根据 X<T> 推导, 产生 T=Unique& .另一方面,X<Unique>根据 X<T&> 推导, 导致推演失败。正如我们所见,模板 #2 更加特化。在步骤 1 中用作参数模板时,推导成功,而模板 #1 在步骤 2 中用作参数模板时,推导失败。因此,第二个更专业的函数模板的特化被称为。
关于c++ - 什么时候两个函数模板被认为是部分有序的,什么时候是不明确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26317798/
类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
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput