C ++模板参数推导/替换失败

时间:2023-01-05 07:18:28

I'm using a template library in which class B is a templated class parametrized by class A. I have a declaration

我正在使用一个模板库,其中B类是由A类参数化的模板化类。我有一个声明

template <class A, template <class A> class B>
void foo(){
   B<A> x;
}

later on I want to invoke this as

后来我想调用它

foo<A, B>();

where X is a concrete class in the library and Y is a particular templated concrete class in the library. However, I get the titled error abour template argument deduction/substitution failed. If I change the declaration of foo to remove the templates and subsitute in X and Y, then it all works ok. I also tried

其中X是库中的具体类,Y是库中特定的模板化具体类。但是,我得到标题错误abour模板参数扣除/替换失败。如果我更改foo的声明以删除模板并替换为X和Y,那么一切正常。我也试过了

foo<X, Y<X> >();

which failed with the same message. Can someone explain why this is happening?

失败了同样的消息。有人可以解释为什么会这样吗?

I'm using gcc 5.3.0

我正在使用gcc 5.3.0

Here's a complete example which gives the indicated behavior

这是一个完整的例子,它给出了指示的行为

#include <vector>
template <class A, template <class A> class B>
void foo() {
   B<A> x;
}
void bar() {
   foo<int, std::vector>();
}

2 个解决方案

#1


2  

You have two issues that I can see.

你有两个问题我可以看到。

First is that std::vector takes more than one template argument so the template template parameter template<class A> class B will never match std::vector.

首先,std :: vector需要多个模板参数,因此模板模板参数模板 class B永远不会匹配std :: vector。

Second and slightly less of an issue is that the class A here template<class A> class B shadows the previous class A here template <class A/*here*/, template <class A> class B>

第二个问题稍微少一点就是这里的A类模板 B类阴影前面的A类模板 class B>

To fix both of these issues you can declare the second template argument as an nameless variadic template like so: template <class...> class B.

要解决这两个问题,您可以将第二个模板参数声明为无名的可变参数模板,如下所示:template class B.

Combining everything you get:

结合你得到的一切:

#include <vector>
template <class A, template <class...> class B>
void foo() {
    B<A> x;
}
void bar() {
    foo<int, std::vector>();
}

Edit:

If you would like to only use B in the form of B<A> you could do one of a few things:

如果您只想以B 的形式使用B,您可以做以下几件事之一:

template <class A, template <class...> class B>
void foo() {
    using C = B<A>;
    C x;
}

OR:

template <class A, template <class...> class B, class C = B<A>>
void foo() {
    C x;
}

OR (depending on the larger point of your code) you could just accept the whole thing as one template parameter:

或者(取决于代码的较大点)您可以将整个事件作为一个模板参数接受:

template <class A>
void foo() {
    A x;
}
void bar() {
    foo<std::vector<int>>();
}

#2


1  

std::vector is not templated on one class, so it does not match your type. You can coerce it to match by

std :: vector在一个类上没有模板化,因此它与您的类型不匹配。你可以强制它来匹配

template <class X> using MyVector = std::vector<X>;

and that will work. C++17 will just plain fix this to work as you expected it to.

这将有效。 C ++ 17将只是简单地修复它以按预期工作。

#1


2  

You have two issues that I can see.

你有两个问题我可以看到。

First is that std::vector takes more than one template argument so the template template parameter template<class A> class B will never match std::vector.

首先,std :: vector需要多个模板参数,因此模板模板参数模板 class B永远不会匹配std :: vector。

Second and slightly less of an issue is that the class A here template<class A> class B shadows the previous class A here template <class A/*here*/, template <class A> class B>

第二个问题稍微少一点就是这里的A类模板 B类阴影前面的A类模板 class B>

To fix both of these issues you can declare the second template argument as an nameless variadic template like so: template <class...> class B.

要解决这两个问题,您可以将第二个模板参数声明为无名的可变参数模板,如下所示:template class B.

Combining everything you get:

结合你得到的一切:

#include <vector>
template <class A, template <class...> class B>
void foo() {
    B<A> x;
}
void bar() {
    foo<int, std::vector>();
}

Edit:

If you would like to only use B in the form of B<A> you could do one of a few things:

如果您只想以B 的形式使用B,您可以做以下几件事之一:

template <class A, template <class...> class B>
void foo() {
    using C = B<A>;
    C x;
}

OR:

template <class A, template <class...> class B, class C = B<A>>
void foo() {
    C x;
}

OR (depending on the larger point of your code) you could just accept the whole thing as one template parameter:

或者(取决于代码的较大点)您可以将整个事件作为一个模板参数接受:

template <class A>
void foo() {
    A x;
}
void bar() {
    foo<std::vector<int>>();
}

#2


1  

std::vector is not templated on one class, so it does not match your type. You can coerce it to match by

std :: vector在一个类上没有模板化,因此它与您的类型不匹配。你可以强制它来匹配

template <class X> using MyVector = std::vector<X>;

and that will work. C++17 will just plain fix this to work as you expected it to.

这将有效。 C ++ 17将只是简单地修复它以按预期工作。