类模板参数推导不使用别名模板

Ant*_*all 27 c++ c++17

考虑下面粘贴的代码.我已经定义了一个非常简单的类,编译器为其生成一个隐式推理指南,因此可以在没有显式模板参数的情况下构造它.但是,模板参数推导不适用于从简单别名模板构造对象,该模板仅直接转发到目标类:

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;
}
Run Code Online (Sandbox Code Playgroud)

正如您从上面的代码注释中看到的那样,g ++给出了一个关于在没有模板参数的情况下使用别名模板的错误.我希望在这样的实例中转发模板参数推导.

所以,我的问题:这是通过表达模板参数演绎提案的当前措辞的明确设计吗?或者这是该功能的当前g ++实现中未完成的功能还是错误?对于提案的作者或C++ ISO委员会来说,这将是一个更大的问题,但如果其中任何一个人看到这一点:是否希望该功能的最终措辞包括启用别名模板,例如是否为他们生成了隐含指南?

我可以理解,因为别名模板可以有任何类型的模板参数,编译器可能并不总是能够成功推导出目标类模板参数,但在这种情况下,我希望编译器能够在它可以直接用于目标类.

几天前,我正在使用gcc构建的gcc --std=c++1z.完整的版本信息是:gcc version 7.0.0 20161201 (experimental) (Homebrew gcc HEAD- --with-jit)

Ric*_*ith 31

这是我们在制定提案时考虑的一个功能,但它最终被削减,因为我们还没有足够好的设计.特别是,关于如何从别名模板中选择和转换演绎指南到别名模板的演绎指南,有一些细微之处.如果别名模板不是另一个模板的简单别名,那么还有一些关于如何表现的问题.一些例子:

template<typename T> struct Q { Q(T); };     // #1
template<typename T> struct Q<T*> { Q(T); }; // #2
template<typename T> using QP = Q<T*>;
int *x;
Q p = x;  // deduces Q<int*> using #1, ill-formed
QP q = x; // deduces Q<int*> using #1, or
          // deduces Q<int**> using #2?

template<typename T> Q(T) -> Q<T>; // #3
QP r = x; // can we use deduction guide #3 here?

template<typename T> Q(T*) -> Q<T**>; // #4
int **y;
QP s = y; // can we use deduction guide #4 here?
Run Code Online (Sandbox Code Playgroud)
template<typename T> struct A { typedef T type; struct Y {}; };
template<typename T> using X = typename A<T>::type;
template<typename T> using Y = typename A<T>::Y;
X x = 4;           // can this deduce T == int?
Y y = A<int>::Y(); // can this deduce T == int?
Run Code Online (Sandbox Code Playgroud)

对上述问题有合适的答案,但解决这些问题会增加复杂性,并且似乎不允许扣除C++ 17的别名模板,而不是匆匆搞砸.

我预测我们会看到Faisal的一篇论文为C++ 20提出这个功能.

  • @squidbidness行`Q p = x;`使用#1推导出`p`的类型为`Q <int*>`用于类模板参数推导.在选择该类型之后,它推断出`Q <int*>`应该使用`Q <T*>`部分特化,推导出`T = int`.最后,它尝试使用类型为"int*"的参数调用`Q <int*>`构造函数,这不起作用,因为唯一的构造函数(默认/复制/移动ctors除外)采用`int` . (5认同)
  • 谢谢你的澄清.令我困惑的部分是我的心智模型推断出了'p`的类型,并选择了模板专业化作为同一个过程.指出它们是分开的步骤有助于我更好地推理它. (2认同)