C++ 允许引用模板类的模板参数,而不是它的实例。例如fun
下面的函数。
同时有一个特性可以在类定义中省略模板参数。例如在 的定义中template<class T> class A
,我们可以说A
to imply A<T>
。
我发现两个规则都可能产生歧义的情况。此外,我无法解决歧义。这里是一个 MWE,在我的定义中template<class T> class B
我需要将其B
称为模板类而不是B<T>
.
template <template<class> class Y, class T>
auto fun(){return Y<T>{};} // fun can be used with a *template* class
template<class T>
struct A{
friend void f(A a){} //A here is implicitly A<T>, ok
};
template<class T>
struct B{
friend void g(B b){
fun<A, void>(); // here A is a template class, ok
fun<B, void>(); // error: no matching function for call to 'fun' because the compiler sees B<T>, not B
} //A here is implicitly A<T>,
};
int main(){
A<void> a{};
B<void> b{};
g(b);
}
(我需要这样做,因为该函数g
是我想在类中定义的友元函数。)
Clang 3.5 给出了上述错误,GCC 4.9.2 可以接受。最糟糕的是,我无法制定额外的规范并解决歧义。
例如我试过:
fun<struct B, void>();
fun<template<class> struct B, void>();
但仍然得到同样的错误。
有没有办法告诉clang(或有问题的编译器)B
不是B<T>
模板类B
?
(我使用了一些 C++11 语法来简化示例,但问题也适用于 C++98。如果我没有使用正确的命名约定,请更正或告诉我。)