【问题标题】:Declaring "friend" functions fails under Visual Studio 2008在 Visual Studio 2008 下声明“朋友”函数失败
【发布时间】:2010-07-02 16:43:50
【问题描述】:

我正在尝试将全局函数声明为类的“朋友”:

namespace first
{
    namespace second
    {
        namespace first
        {
            class Second
            {
                template <typename T> friend T ::first::FirstMethod();
            };
        }
    }
}

当我在 Visual C++ 2008 下编译这段代码时,我得到:

error C3254: 'first::second::first::Second' : class contains explicit override 'FirstMethod' but does not derive from an interface that contains the function declaration
error C2838: 'FirstMethod' : illegal qualified name in member declaration

如果我改用template &lt;typename T&gt; friend T first::FirstMethod();,我会得到:

error C2039: 'FirstMethod' : is not a member of 'first::second::first'

声明友元函数的适当方式是什么?

【问题讨论】:

  • 更一般地说,我认为嵌套相同的标识符(firstfirst)是一个非常糟糕的主意,它不仅会混淆读者,还会混淆编译器。

标签: c++ visual-studio-2008 friend-function


【解决方案1】:

您无意中点击了my quiz - 序列T ::first:: ... 被解释为单个 名称。您需要在冒号和T 之间放置一些标记。链接的问题中也提供了解决方案。

请注意,在任何情况下,您首先也必须在其各自的命名空间中声明由限定名称指定的函数。


编辑:语法问题有不同的解决方案

 template <typename T> friend T (::first::FirstMethod)();
 template <typename T> T friend ::first::FirstMethod();

如果你经常需要引用外部命名空间,并且对这种语法有问题,可以引入命名空间别名

    namespace first
    {
        namespace outer_first = ::first;
        class Second
        {
            template <typename T> friend T outer_first::FirstMethod();
        };
    }

【讨论】:

  • 优秀的答案。非常感谢!
  • 为什么T ::first:: 被解释为一个名字?如果它是一个单一的名称,则需要有 typename 前缀,不是吗?
  • @smerlin,这是一个非类型名称。这意味着声明声明了名称T::first::FirstMethod,并且没有指定该名称的类型。从语义上讲,这没有任何意义,并使 VC++08 吐出令人困惑的错误消息。 Clang 的诊断要好得多:“错误:C++ 需要所有声明的类型说明符”。当然,您可以在它前面加上“typename”,在这种情况下,它充当类型说明符并且缺少成员名称。 Clang 然后说“错误:预期的成员名称或';'在声明说明符之后"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 2013-08-27
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多