已编辑(原始问题只有int A,int B):
模板参数推断在两个专门化之间比较的#参数相同时按预期工作,但在它们不同时失败(因为在其中一个专门化中包含默认参数)。
例如:为什么模板参数推导在一种情况下与另一种情况下失败,有人能指出解释这一点的任何资源/标准吗?
// Example program
#include <iostream>
template <int A, int B, int C, int D=1>
class Foo;
template <int A, int B, int C>
class Foo <A, B, C>
{
public:
int a;
Foo()
{
a = 0;
}
};
template <int D> // Fails compilation
class Foo <1, 1, 1, D> // Fails compilation
//template <> // works, prints a = 1
//class Foo <1, 1, 1> // works, prints a = 1
{
public:
int a;
Foo()
{
a = 1;
}
};
int main()
{
Foo <1, 1, 1, 1> f;
std::cout << "a = "<< f.a << std::endl;
}
错误:模糊模板实例化'类Foo
template <int A>
class Foo <A> {/*..*/};
具有默认参数:
template <int A>
class Foo <A, 1> {/*..*/};
附(有效):
template <int B>
class Foo <1, B> { /*..*/ };
您对Foo有歧义
template <> class Foo <1> { /**/};
是
template <> class Foo <1, 1> { /**/};
并且比以前的两个专业都更专业。
如果允许我执行以下操作: 为什么我主要不被允许做以下事情? 但我必须具体说明以下几点: C11引入了默认的模板参数,现在我完全无法理解它们。
考虑下面粘贴的代码。我定义了一个非常简单的类,编译器为其生成一个隐式推导指南,这样就可以在没有显式模板参数的情况下构造它。但是,模板参数推导不适用于从仅直接转发到目标类的简单别名模板构造对象: 正如您从上面的代码注释中看到的,g给了我一个关于使用别名模板而没有模板参数的错误。我希望在这样的例子中,模板参数推导会被转发。 所以,我的问题是:这是通过明示设计目前的措辞来对班级模板的论点进行演绎的建议吗
标准中似乎没有规则提到模板参数需要默认参数的情况。 在dcl中。fct。默认值#1 如果在参数声明中指定了初始化子句,则将此初始化子句用作默认参数。缺省参数将用于缺少尾随参数的调用。 在本节中,规则明确描述了何时为函数调用提供默认参数。但是,我在标准中没有找到与上面描述何时提供默认参数作为模板参数的语句类似的引用。 例如
是否允许在友元声明中为模板参数提供默认值? Visual Studio 2015似乎允许这样做。gcc拒绝了。我在cppreference页面上找不到任何内容。
N4527 14.8.2.4[温度扣除部分] 3用于确定排序的类型取决于进行部分排序的上下文: (3.1)-在函数调用的上下文中,使用的类型是那些函数调用具有参数的函数参数类型。 (3.2)-在调用转换函数的上下文中,使用转换函数模板的返回类型。 (3.3)-在其他上下文(14.5.6.2)中使用函数模板的函数类型。 4以上从参数模板中指定的每种类型以及从参数模板中指定的相应类型都用作P和A的类型
https://stackoverflow.com/a/22487113/4416169在下面的答案中,我们可以看到详细的代码: https://stackoverflow.com/a/35652391/4416169在这里,我们可以看到如何选择模板: 选择模板专门化分为五个步骤: 以主模板声明为例 首先,我知道SFINAE将负责使用std::enable\u if排除结构 模板 我们现在知道,当