当我有一个接受向量的类对象时,比较下面的情况。未推导的参数T可以用默认的模板参数很好地替换:
#include <vector>
template <typename T = int>
struct container
{
container(std::vector<T> vec) {}
};
int main()
{
container C = std::vector{1,2,3,4,5};
}#include <cstdio>
#include <initializer_list>
#include <variant>
template <size_t> struct obj;
template<size_t Vs>
using val = std::variant<std::monostate, int, struct obj<Vs>>;
template <size_t Vs = 0>
struct obj
{
obj() = default;
obj(std::initializer_list<val<Vs>> init) {
printf("initializer of object called, Vs = %d\n", Vs);
}
};
template <size_t Vs = 0>
struct container : public obj<Vs>
{
container(obj<0> init) {}
};
int main()
{
container<5> some_container = obj{1,2,5,2,obj{1,2,33},2,2};
}如果出现以下错误,这将失败:
<source>: In function 'int main()':
<source>:29:57: error: class template argument deduction failed:
29 | container<5> some_container = obj{1,2,5,2,obj{1,2,33},2,2};
| ^
<source>:29:57: error: no matching function for call to 'obj(int, int, int)'
<source>:14:5: note: candidate: 'template<long unsigned int Vs> obj(std::initializer_list<std::variant<std::monostate, int, obj<Vs> > >)-> obj<<anonymous> >'
14 | obj(std::initializer_list<val<Vs>> init) {
| ^~~但是,当我在容器实例化中补充模板专门化obj<0> (在main中)时,它可以工作。你知道为什么这对我的课不起作用吗?我怎样才能解决它?我不想强迫用户每次指定模板。
发布于 2022-07-18 17:13:24
这个问题在更简单的情况下已经存在。
auto o = obj{1,2,33};从而产生此错误:
<source>:29:24: error: class template argument deduction failed:
29 | auto o = obj{1,2,33};
| ^
<source>:29:24: error: no matching function for call to 'obj(int, int, int)'
<source>:14:5: note: candidate: 'template<long unsigned int Vs> obj(std::initializer_list<std::variant<std::monostate, int, obj<Vs> > >)-> obj<<anonymous> >'
14 | obj(std::initializer_list<val<Vs>> init) {
| ^~~
<source>:14:5: note: template argument deduction/substitution failed:
<source>:29:24: note: mismatched types 'std::initializer_list<std::variant<std::monostate, int, obj<Vs> > >' and 'int'
29 | auto o = obj{1,2,33};因此,编译器无法推断出这三个int应该是一个初始化程序列表。如果在它们周围添加额外的大括号,编译器就会意识到这实际上应该是一个列表参数,而不是三个单独的参数,它可以工作:
auto o = obj{{1,2,33}};这也涉及到更复杂的情况:
container some_container = obj{{1,2,5,2,obj{{1,2,33}},2,2}};https://stackoverflow.com/questions/73025961
复制相似问题