N4527 14.8.2.4 [temp.deduct.partial]
3用于确定排序的类型取决于完成部分排序的上下文:
(3.1) - 在函数调用的上下文中,使用的类型是函数调用具有参数的函数参数类型。
(3.2) - 在调用转换函数的上下文中,使用转换函数模板的返回类型。
(3.3) - 在其他上下文(14.5.6.2)中使用了函数模板的函数类型。
4从参数模板中提取的每种类型以及参数中的相应类型 模板用作
P
和A
的类型。8如果
A
从函数参数包转换而P
不是参数包,则类型推导失败。 否则,使用结果类型P
和A
,然后按照14.8.2.5中的描述进行推导。如果P
是一个函数参数包,参数模板的每个剩余参数类型的类型A
是 与函数参数包的declarator-id的类型P
进行比较。每个比较推断 由函数扩展的模板参数包中后续位置的模板参数 参数包。如果给定类型的推导成功,则考虑参数模板中的类型 至少与参数模板中的类型一样专业。 [例如:
template<class... Args> void f(Args... args); // #1
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
f(); // calls #1
f(1, 2, 3); // calls #2
f(1, 2); // calls #3; non-variadic template #3 is more
// specialized than the variadic templates #1 and #2
为什么f(1, 2, 3);
会调用#2?
我需要更多详情,包括:
1它是哪个背景?
2什么是转化的?从#1转换而来的是void (U)
,void (U...)
或其他形式?(U
表示唯一类型)
14.5.6.2 [temp.func.order] / p3
为每种类型,非类型或模板模板参数生成转换后的模板(包括 模板参数包(14.5.3)分别合成唯一的类型,值或类模板 并将其替换为模板函数类型中每次出现的参数。
3扣除中使用的P
和A
有哪些类型?例如
template <class T> void f(T);
int a = 1;
f(a);//P = T, A = int
答案 0 :(得分:4)
为什么
f(1, 2, 3);
会调用#2?
你的问题中有很多问题(请问每个问题一个问题!),所以我会坚持这个问题。首先,我们执行模板推导。 #3失败,但#1和#2成功:
template<class... Args>
void f(Args... args); // #1, with Args = {int, int, int}
template<class T1, class... Args>
void f(T1 a1, Args... args); // #2, with T1 = int, Args = {int, int}
这两个函数按值int
取三个,因此过载分辨率下所有正常的断路器都无法解决模糊性问题。所以我们到了最后一个:
鉴于这些定义,如果对于所有参数
F1
,ICS i ,可行函数F2
被定义为比另一个可行函数i
更好的函数。 (F1
)并不比ICS i (F2
)更糟糕的转换序列,然后是 - [...]
-F1
和F2
是函数模板特化,F1
的函数模板更专业 根据14.5.6.2中描述的部分排序规则,F2
的模板。
规则是:
第1步:合成类型[temp.func.order]:
为每种类型,非类型或模板模板参数生成转换后的模板(包括 模板参数包(14.5.3)分别合成唯一的类型,值或类模板 并将其替换为模板函数类型中每次出现的参数。
所以我们有:
void f(Pack1... args); // #1
void f(U2 a1, Pack2... args); // #2
第2步:执行[temp.deduct.partial]中所述的演绎。我们所处的上下文是函数调用,因此我们使用函数调用具有参数的类型。
首先,我们尝试从#1推断#2。也就是说,我们尝试匹配(T1, Args...
)与(Pack1...)
。第一部分是P = T1, A = Pack1...
。我们有:
如果A是从函数参数包转换而P不是参数包,则类型推导失败。
因此从#1中推导#2失败,因此参数Args...
至少不如T1, Args...
那么专业。
接下来,我们尝试从#2中推断#1。也就是说,我们尝试将(Args...)
与(U2, Pack2...)
匹配。这很成功,因此T1, Args...
至少与Args...
一样专业。
由于#2至少与#1一样专业,而#1至少不像#2那样专业,我们可以说#2更专业化:
函数模板
F
至少与函数模板G
一样专用,如果对于每对类型用于 确定排序,F
中的类型至少与G
中的类型一样专业。F
更专业 如果G
至少与F
一样专业,而G
至少与G
一样专业,则F
比<script> var buttons = { Join: { text: '{translate id=1434}', click: function(e) { e.preventDefault(); showLoadingScreen(); showMiniSearchLoadingScreen(); performAction({ action: "addPlayer", playerid: {$playerdetails.player_id}, starting: 1, leagueid: memberleagueid }); // close dialog after adding player $( this ).dialog( "destroy" ); } } } $( "#dialog" ).dialog({ resizable: false, width: 855, height: 650, modal: true, dialogClass: 'no-close fixed-dialog player-profile-dialog', buttons: buttons, }).attr('id', 'dialog'); function newPopup(url) { popupWindow = window.open( url,'popUpWindow','height=700,width=960,left=10,top=10,resizable=no,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes') } $(document).ready(function() { // Get context with jQuery - using jQuery's .get() method. var ctx = document.getElementById("myChart").getContext("2d"); var data = { labels: ["January", "February", "March", "April", "May", "June", "July"], datasets: [ { label: "My First dataset", fillColor: "rgba(220,220,220,0.2)", strokeColor: "rgba(151,187,205,1)", pointColor: "rgba(151,187,205,1)", pointStrokeColor: "#fff", pointHighlightFill: "#fff", pointHighlightStroke: "rgba(220,220,220,1)", data: [65, 59, 80, 81, 56, 55, 40] } ] }; var options = { //animation: false, //scaleoverride: true, responsive: false, maintainAspectRatio: true, bezierCurve: false, animationSteps: 1, scaleShowGridLines: true, scaleShowLabels: true, pointHitDetectionRadius: 5, pointDotRadius: 3, pointDotStrokeWidth: 0, scaleFontColor: "#2b2b2b", tooltipFillColor: "rgba(255, 255, 255, 0.8)", tooltipFontColor: "#2b2b2b", tooltipFontSize: 12, multiTooltipKeyBackground: "transparent", tooltipStrokeColor: "rgba(43,43,43,0.7)", tooltipTitleFontColor: "#2b2b2b", multiTooltipTemplate: {literal}'<% if (datasetLabel) {%><%= datasetLabel %>: <%= value %> <%if ( optional.ranking ) {%> - {/literal}{translate id=480}{literal}: <%= optional.ranking %> <%} }%>',{/literal} legendTemplate: {literal}"<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){ if (datasets[i].label) {%><li><span class=\"chartLegendColor\" style=\"background-color:<%=datasets[i].pointColor%>\"></span><%if(datasets[i].label){%><span class=\"chartLegendLabel\"><%=datasets[i].label%></span><%}%></li><%} }%></ul>"{/literal} }; var myLineChart = new Chart(ctx).Line(data, options); });
更长。
首选更专业的模板,因此我们称之为#2。