作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我在理解允许对构造函数进行模板推导的新 C++17 功能的所有限制时遇到了一些困难。
特别是,这个例子编译正确:
struct B {};
template <typename T, typename = T>
struct A {
A(T) {}
};
int main() {
B b;
A a(b); // ok
}
虽然这个没有:
struct B {};
template <typename T, typename = T>
struct A;
template <typename T>
struct A<T> {
A(T) {}
};
int main() {
B b;
A a(b); // error
}
第二种情况的错误是:
main.cpp: In function ‘int main()’:
main.cpp:17:14: error: class template argument deduction failed:
A a(b);
^
main.cpp:17:14: error: no matching function for call to ‘A(B&)’
main.cpp:4:12: note: candidate: template<class T, class> A(A<T, <template-parameter-1-2> >)-> A<T, <template-parameter-1-2> >
struct A;
^
main.cpp:4:12: note: template argument deduction/substitution failed:
main.cpp:17:14: note: ‘B’ is not derived from ‘A<T, <template-parameter-1-2> >’
A a(b);
^
为什么会这样?
最佳答案
类模板参数推导只考虑来自primary 类模板的构造函数来进行推导。在第一个示例中,我们有一个构造函数,我们为其合成了一个函数模板:
template <class T> A<T> __f(T );
__f(b)
的结果是A<B>
,我们就完成了。
但是在第二个例子中,主类模板只是:
template <typename T, typename = T>
struct A;
它没有构造函数,所以我们没有可以从中合成的函数模板。我们只有一个 hypothetical default constructor和 copy deduction guide ,它们一起给了我们这个重载集:
template <class T> A<T> __f();
template <class T> A<T> __f(A<T> );
对于 __f(b)
这两个都不可行(你得到的编译错误是关于尝试匹配复制推导指南),因此推导失败。
如果你想成功,你必须写一个推导指南:
template <class T>
A(T ) -> A<T>;
这将允许 A a(b)
去工作。
关于c++ - 具有部分特化的类模板参数推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46118787/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!