考虑粘贴在下面的代码。我已经定义了一个非常简单的类,为此编译器生成一个隐式演绎指南,因此它可以在没有显式模板参数的情况下构建。但是,模板参数推导不工作从只直接转发到目标类的简单的别名模板构造一个对象:类别模板参数扣除不与别名模板一起使用
template< typename A, typename B >
struct Foo {
Foo(A const &a, B const &b)
: a_(a), b_(b)
{ }
A a_;
B b_;
};
template< typename A, typename B >
using Bar = Foo<A, B>;
auto foobar() {
Foo r{1, 2};
Bar s{3, 4};
// ../src/geo/vector_test_unit.cpp: In function 'auto foobar()':
// ../src/geo/vector_test_unit.cpp:16:6: error: missing template arguments before 's'
// Bar s{3, 4};
// ^
return 1;
}
正如你可以从上面的代码注释看,G ++是给我有关使用没有模板参数的别名模板的错误。我希望在这种情况下,模板论证扣除将被转发。
那么,我的问题:这是通过明确设计类模板参数演绎提案的当前措词吗?或者,这是该功能的当前g ++实现中未完成的功能或缺陷?这对于提案的作者或者C++ ISO委员会来说可能是一个更大的问题,但是如果他们中的任何一个人看到这样的话:这个特性的最后措辞是否包括启用别名模板也是理想的为他们生成隐式指南?
我可以理解,由于别名模板可以具有任何类型的模板参数,因此编译器可能无法总是成功推导出目标类模板参数,但在这种情况下,我希望编译器会是能够以同样的方式直接为目标课程。
我在前几天使用gcc构建gcc,使用--std=c++1z
。完整版本信息是:gcc version 7.0.0 20161201 (experimental) (Homebrew gcc HEAD- --with-jit)
我一次建立并编译您的示例文件,试图逐步了解它。我只用#1,#2和行int * x编译了它; Q p = x;'。正如你所指出的,它会给出一个错误,除非我删除#2并重新编译。来自g ++的错误信息是'[...]错误:从'int *'到'int'的无效转换... Q p = x; ...注意:初始化'Q :: Q(T)[with T = int]'参数1'template struct Q {Q(T); };'。对我来说,就像你说的那样,它试图使用#2而不是#1。我不了解什么? –
@squidbidness对于类模板参数推导,'Q p = x;'这一行使用#1推导'p'的类型为'Q'。选择该类型后,它推断'Q '应该使用'Q '部分专业化,推导出'T = int'。最后,它试图调用一个'Q '构造函数,其参数类型为'int *',因为唯一的构造函数(默认/复制/移动ctors除外)需要一个int类型,所以它不起作用。 –
谢谢你的澄清。让我感到困惑的部分是我的心智模型已经推导出'p'的类型,并且选择一个模板专业化作为一个相同的过程。指出他们是单独的步骤帮助我更好地推理它。 –