C++ 为什么可以';通过模板参数声明友元函数的类型,但可以使用别名

C++ 为什么可以';通过模板参数声明友元函数的类型,但可以使用别名,c++,templates,friend,C++,Templates,Friend,以代码为例: template <class T> class Bar { int foobar; using X = T(); friend X foo; }; void foo() { Bar<void> bar; bar.foobar = 1; static_cast<void>(bar); } int main() {} 模板 分类栏{ int foobar; 使用X=T(); 朋友X富,; };

以代码为例:

template <class T>
class Bar {
    int foobar;
    using X = T();
    friend X foo;
};

void foo() {
    Bar<void> bar;
    bar.foobar = 1;
    static_cast<void>(bar);
}

int main() {}
模板
分类栏{
int foobar;
使用X=T();
朋友X富,;
};
void foo(){
酒吧;
bar.foobar=1;
静态浇铸(棒材);
}
int main(){}
编译和都很好。但看似等效的代码:

template <class T>
class Bar {
    int foobar;
    friend T foo;
};

void foo() {
    Bar<void()> bar;
    bar.foobar = 1;
    static_cast<void>(bar);
}

int main() {}
模板
分类栏{
int foobar;
朋友T foo,;
};
void foo(){
酒吧;
bar.foobar=1;
静态浇铸(棒材);
}
int main(){}

在和中都会导致错误。为什么模板参数在这里的作用与alias不同?

因为
t foo
被解析为对象的声明,模板的实例化不能将对象的声明更改为函数的声明

C++标准/[临时规范]:

如果函数声明通过依赖类型(17.7.2.1)获得其函数类型,而不使用 函数声明器的语法形式,程序格式不正确


我花了一点时间才注意到您在其中一个中发送了
void
,在另一个中发送了
void()
。“crash”通常并不是您使用它的意思。还有,@t.C.抱歉-editingWell。。。我认为T.C.解决了这个问题……是的,这很奇怪,因为你不能将一个物体声明为朋友,但我认为这是根本原因。谢谢是的,的确很奇怪。实际上,编译器知道friend不能是一个对象,并且由于对象声明不能转换为函数声明,所以他们在任何实例化之前都会预测问题并报告错误。