- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我希望第一个代码示例的最后两行打印相同的内容。
类型将按照我的预期进行扣除,并且过载解析度也将符合我的预期。
但是,如果我显式地键入限定函数调用的值,则推论出类型时,得到的结果将不同。
第二个代码示例重复该练习,以专用化替换重载分辨率。在这种情况下,一切都会按预期进行。
有什么解释吗?
编辑:我又增加了一行,显示Karthik提到的关于print<R,int>(r);
的内容,我也不明白。
代码示例1 :(功能模板重载)
#include <iostream>
template <typename T>
void print (T i)
{
std::cout << "simple" << std::endl;
}
template <template<typename> class FF, typename TT>
void print (FF<TT> i)
{
std::cout << "template" << std::endl;
}
template <typename T1, typename T2>
void print (T1 a)
{
T2 b;
std::cout << "two type parameters" << std::endl;
}
template <>
void print<int>(int i)
{
std::cout << "int" << std::endl;
}
template <typename T>
struct R
{
T x;
};
int main()
{
R<int> r;
print<int>(1.1); // ok, prints "int"
print(1.1); // ok, prints "simple"
print<int>(1); // ok, prints "int"
print(1); // ok, prints "int"
print(r); // ok, prints "template"
print<int,int>(1); // ok, prints "two type parameters"
print<R<int>,int>(r); // ok, prints "two type parameters"
print<R<int> >(r); // (1) ?? why "simple" ??
print<R,int >(r); // (2) ?? prints "template", why does it compile at all ??
// gcc 4.6.2 (-std=c++0x) and 4.8.1 (-std=c++11)
// clang++ 3.3.1 same behavior as gcc
}
#include <iostream>
template <typename T>
struct P
{
static void print (T i)
{
std::cout << "simple" << std::endl;
}
};
template <template<class TT> class FF, typename TT>
struct P <FF<TT> >
{
static void print (FF<TT> i)
{
std::cout << "template" << std::endl;
}
};
template <>
struct P<int>
{
static void print(int i)
{
std::cout << "int" << std::endl;
}
};
template <typename T>
struct R
{
T x;
};
int main()
{
R<int> r;
P<double>::print(1.1); // ok, prints "simple"
P<int>::print(1); // ok, prints "int"
P<R<int> >::print(r); // ok, prints "template"
//P<R,int >::print(r); // ok, does not compile
}
最佳答案
好吧,让我们看一下编译器对每一个的看法。
template <typename T> void print (T i); // (1)
template <template<typename> class FF, typename TT> void print (FF<TT> i); // (2)
template <typename T1, typename T2> void print (T1 a); // (3)
template <> void print<int>(int i); // (4)
print<int>(1.1); // ok, prints "int"
T1
固定为
int
;但是,无法推导
T2
,因此它也消失了。选择参数
T
为
int
的1。这匹配特化4。
print(1.1); // ok, prints "simple"
double
。 1场比赛;
T
是 double 的。 2需要模式
FF<TT>
,而
double
与之不匹配,因此会失败。 3可以将
T1
推导为
double
,但是对于
T2
没有任何帮助,因此它也失败了。选择1。专业不匹配。
print<int>(1); // ok, prints "int"
print(1); // ok, prints "int"
int
(仍然不匹配
FF<TT>
),因此特化匹配。
print(r); // ok, prints "template"
T = R<int>
。对于2,
R<int>
与
FF<TT>
模式匹配,因此它是可行的,并带有
FF = R
和
TT = int
。 3,像往常一样,不知道该如何处理
T2
。重载解析获得1和2(同一性)的相同序列,因此部分功能模板排序解决了歧义:2比1更专业,因此被选择。
print<int,int>(1); // ok, prints "two type parameters"
print<R<int>,int>(r); // ok, prints "two type parameters"
R<int>
而不是
int
,但这仍然只是一个类型,而2不喜欢它。
print<R<int> >(r); // (1) ?? why "simple" ??
T2
,2要以模板作为第一个参数,因此1是唯一选择。
R<int>
是一种类型,而不是模板。
print<R,int >(r); // (2) ?? prints "template",
When I replace function overloading with template specialization, then template pattern matching works as I would have expected. I have some trouble believing that the pattern matching rules also differ between classes and functions.
template <typename T> void print(T i);
template <template <typename> class FF, typename TT> void print(FF<TT> i);
template <template <typename> class FF, typename TT> void something_else(FF<TT> i);
something_else<R, int>(r);
是有效的吗?您有一个带有两个参数的模板,并且传递了两个参数。仅有一个参数的另一个模板的存在不会改变这一点!
template <typename T> class Q {};
template <template <typename> class FF, typename TT> class Q {};
redef.cc:2:5: error: too many template parameters in template redeclaration
Q
,并抱怨模板参数列表不匹配。
template <typename T> class P {};
template <template <typename> class FF, typename TT> class P<FF<TT>> {};
redef.cc:2:64: error: explicit specialization of non-template class 'P'
P
,并且它具有一个模板参数。如果此参数采用特定形式,则特化将匹配,但是与第一个示例中的第二个功能模板不同,该特化不是具有两个参数的独立模板。
P<R<int>>::print(r)
可以编译和起作用的原因:
P
具有一个参数,并为其传递了
R<int>
。部分特化匹配模式,因此被选择。但是
P<R, int>::print(r)
不起作用:
P
仅具有一个模板参数,在这里您尝试传递两个。特化不是它自己的实体,因此不被考虑。
template <> void print<int>(int i)
不是。
关于c++ - 函数重载匹配模板template,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18565509/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!