Naz*_*kyi 6 c++ templates template-templates type-deduction
当我实例化模板类时,Visual Studio没有看到正确的构造函数。我在哪里弄错了?
我已经尝试过使复制/移动构造函数显式/删除。无济于事。
#include <set>
using namespace std;
template <class T, template<class> class ConnectionType>
struct node
{
T value;
node(const T& value) : value(value) {}
set<ConnectionType<T>> connections;
};
template <class T>
struct connection
{
node<T, connection>* n;
connection(node<T, connection>* n) :
n(n) {}
bool operator<(const connection& b) const
{
return n < b.n;
}
};
int main()
{
node<int, connection> a(0);
connection<int> c(&a); // ERROR HERE
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误:
error C2664: 'connection<T>::connection(connection<T> &&)': cannot convert argument 1 from 'node<int, connection> *' to 'node<T, connection<T>> *'
Run Code Online (Sandbox Code Playgroud)
似乎是VS的错误。VS似乎将注入的类名 connection
视为与等效的类型名connection<T>
,但应将其视为类模板本身的模板名,即connection
in node<T, connection>* n;
和中connection(node<T, connection>* n)
,因为的第二个模板参数node
是模板模板参数。
(强调我的)
在以下情况下,injected-class-name被视为类模板本身的模板名称:
- 它后面跟着<
- 它用作与模板模板参数相对应的模板参数
- 它是朋友类模板声明的详细类说明符中的最终标识符。
否则,将其视为类型名称,并且等效于模板名称,后跟<>中包含的类模板的模板参数。
Run Code Online (Sandbox Code Playgroud)template <template <class, class> class> struct A; template<class T1, class T2> struct X { X<T1, T2>* p; // OK, X is treated as a template-name using a = A<X>; // OK, X is treated as a template-name template<class U1, class U2> friend class X; // OK, X is treated as a template-name X* q; // OK, X is treated as a type-name, equivalent to X<T1, T2> };
PS:您的代码可以使用clang很好地编译。
PS:视为connection<T>
中bool operator<(const connection& b) const
。
在类模板的范围内,模板的名称实际上是“注入的类名称”,其作用类似于类成员,并且可以用作模板名称或类型名称,这意味着使用中的专业化。([本地温度]/1)
因此,当这个名称用作模板参数时,它可能意味着其中之一,因此编译器需要检查相应的模板参数是类型还是模板。g++ 和 clang++ 按原样接受您的代码。但是 MSVC 有一个错误,它经常(但并非总是)假设用作模板参数的注入类名是类类型,即使唯一相关的模板参数是模板模板参数。(原代码上的三个编译器:https ://godbolt.org/z/xrJSPB )
要解决此问题,您可以使用限定名称,就像::connection
在其自身范围内表示模板名称一样。
template <class T>
struct connection
{
node<T, ::connection>* n;
connection(node<T, ::connection>* n) :
n(n) {}
bool operator<(const connection& b) const
{
return n < b.n;
}
};
Run Code Online (Sandbox Code Playgroud)
(所有三个编译器都接受这一点: https: //godbolt.org/z/st7liP)
归档时间: |
|
查看次数: |
80 次 |
最近记录: |