3

いくつかのコードを書いているときに、この問題に遭遇しました:


#include <iostream>

class random { public: random(){ std::cout << "yay!! i am called \n" ;} };

random r1 ;

int main() { std::cout << "entry!!\n" ; static random r2; std::cout << "done!!\n" ; return 0 ; }

このコードをコンパイルしようとすると、エラーが発生します
error: ârandomâ does not name a type.
クラスに別の名前を使用すると、コードは正常に機能します。
は別の場所で定義されているようrandomです (ただし、コンパイラ メッセージはあまり有益ではありません)。

私の質問は、使用している名前が含まれているファイルで使用されている名前と衝突しないことをどのように保証できるかです。名前空間を使用してみましたが、呼び出し時にあいまいさが生じます。洞察はありますか?
[編集]
名前空間を as としてusing namespace myNSpace
使用しましたが、use myNSpace::randomそれを使用すると正常に機能しました。

4

10 に答える 10

8

名前空間を使用する

namespace myNamespace
{

    class random
    {
    public:
        random(){ std::cout << "yay!! i am called \n" ;}
    };

}

myNamespace::random r1;
于 2009-12-04T15:51:48.457 に答える
5

POSIXrandom()関数を実行しています。

衝突をどのように回避しますか?あなたのライブラリを知っています。または、これを診断するために私が行ったように行うことができますman random。そこに、random(3)がありました。

名前空間の問題が何であるかはわかりませんが、別の質問のように聞こえます。

于 2009-12-04T15:53:29.733 に答える
2

私にはあなたの特定のコンパイラの問題のように見えます。私が手元にあるコンパイラではエラーは発生しません。

于 2009-12-04T15:50:33.750 に答える
2

名前の衝突の問題がある場合は、名前空間を使用してください。

namespace mydata{
 class random{things};
}

そしてそれを呼ぶmydata::random;

于 2009-12-04T15:52:33.917 に答える
2

あなたが働いているのに、なぜあなたは働かusing namespace...ないのusing ...ですか?最初に、精巧な型指定子を使用してそれを解決する別の方法を示したいと思います。

int main() {
  // ...
  static class random r2; // notice "class" here
  // ...
}

「class some_class」は精巧な型指定子であり、指定した名前を検索するときに型以外の宣言を無視するため、これが機能します。そのため、同じ名前を持つグローバルスコープの POSIX 関数はクラス名を隠しません。それを解決するために、他の 2 つの方法を試しました: ディレクティブの使用と宣言の使用:

  • 次に、タイプを名前空間に貼り付けようとしusing namespace foo;、メインで試しました-なぜ機能しなかったのですか?

    namespace foo {
    class random
    {
     public:
     random(){ std::cout << "yay!! i am called \n" ;}
    };
    }
    
    int main() {
     using namespace foo; 
     static random r2; // ambiguity!
     return 0 ;
    }
    

    foousing ディレクティブは名前を main のローカル スコープ内で宣言していると考えているかもしれませんが、そうではありません。名前を宣言しているわけではありません。実際には、別の名前空間へのリンクにすぎません。その場合、修飾されていない名前の検索中に名前が表示されますが、名前は using ディレクティブと指定された名前空間 ( foo) の両方を囲む名前空間のメンバーとして表示されます。その囲んでいる名前空間は、ここではグローバル名前空間です。

    そのため、名前検索では、その名前の 2 つの宣言が検出されます。グローバル POSIXrandom宣言と、.NET 内のクラス宣言ですfoo。宣言は同じスコープ (宣言領域) で行われていないため、関数名は通常のようにクラス名を隠しません (man stat例については、を参照してください)。ただし、結果はあいまいになります。

  • ただし、 using宣言は、それが現れる宣言領域のメンバーとして 1 つの名前を宣言します。したがって、 をrandomから検索すると、 inmainの宣言を参照する名前が最初に見つかります。これにより、グローバル POSIX が効果的に隠されます。関数。したがって、次のように動作しますrandomfoo

    namespace foo {
    class random
    {
     public:
     random(){ std::cout << "yay!! i am called \n" ;}
    };
    }
    
    int main() {
     using foo::random; 
     static random r2; // works!
     return 0 ;
    }
    
于 2009-12-04T17:20:55.160 に答える
1

これらの問題を回避するには、名前空間を使用します.. wikipedia

namespace myNamespace
{
     class random
     {
         ....
     };
}
于 2009-12-04T15:53:48.190 に答える
1

一般に、曖昧なエラーは明示的に解決することで回避します。重複するシンボルを別の名前空間に配置しないと、同じ名前空間に 2 つのシンボルがあり、それらのいずれかを明示的に参照できないため、これは機能しません ( litb が指摘するように、精巧な型指定子が役立つ場合を除きます)。

シンボルを名前空間に配置すると、次のことができます。

  • 名前を完全修飾します。myNamespace::mySymbol(x);
  • あいまいさを明示的に解決します。using myNamespace::mySymbol;

via で名前空間からすべてのシンボルを取得してusing myNamespace;も、あいまいさが解決されないため、役に立たないことに注意してください。

完全修飾の場合、短縮名を使用するのが一般的です。

namespace mns = myNamespace;
mns::mySymbol(x);
于 2009-12-04T17:07:05.530 に答える
0

cstdlib を含めていますか? 含めると表示されるエラーが表示されますが、含めない場合は表示されません。

于 2009-12-04T16:18:41.353 に答える
0

プログラムを正しくコンパイルして実行したg ++コンパイラ。Windowsでg ++を実行するためにMinGw 5.1.6を使用しています..

于 2009-12-04T16:35:26.653 に答える