以下代码应该是不言自明的。我有两个关于使用的语法(这是必须使用的语法)的问题。如果您能为我提供这些问题的答案,我将永远感激不尽。

template <typename T>
struct A {
    template <typename S>
    void f (const A<S> &s);

    template <typename S>
    friend struct A;
    // Question 1: why isn't the syntax 'friend struct A<S>' ?
    // The semantic would stay, since we would like A<S> (for ANY S) to be friend of every A<T>..

    private:
        void g () const {}
};

template <typename T>
template <typename S> // Question 2: Why can't the syntax be 'template <typename T, typename S>' ?
void A<T>::f (const A<S> &s) {
    s.g();
}

int main () {
    A<bool> abool;
    A<char> achar;

    abool.f(achar);
}

我已经证实这确实是唯一正确的语法(我很高兴发现我错了)。我的问题更多是关于语法背后的推理,如问题正文中所述。

谢谢你的帮助。

最佳答案


你希望我们说什么?决定这种语法的人(主要是 Stroustrup 本人,AFAIK)认为他们的语法比你的好。
我不知道哪个更好或更容易记住 - 但我确实发现他们的比你的更有意义。你当然可以不同意。
编辑: 好的, Alexander has nicely answered question #2 。关于#1:
不同之处在于 A<S> 命名了一个类型,这是函数参数所期望的,而 A 本身是一个模板的名称,要从中创建类型,如果您想与模板交 friend 而不是一种:

template <typename S>
void f (const A<S> &s); // A<S> being the name of a type

template <typename S>
friend struct A; // A being the name of a template
您可以与特定模板实例而不是整个模板成为 friend ,但为此模板必须已被编译器(即声明)在 friend 声明中知道:
template< typename T >
class foo;

class bar {
  friend class foo<int>; // foo<int> being the name of a specific instance of foo
};
因此,与模板成为 friend 是一个异常(exception)(“通常的” friend 声明声明了一个函数或类)并且确实需要不同的语法。

关于c++ - 一个涉及非平凡模板和友元声明的 C++ 语法问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2172919/

10-14 16:45
查看更多