

そうしたい理由というのは、現在あるクラス(class
Hogeとします)をシングルトンとしているのですが、「public:」の次の行の関数のみHoge.cppを参照し、以降の行はmain.cppを参照しているようなのです。定義に移動(F12)で確認しています。そのせいで「関数定義が見つかりません」と怒られます(なのにLINL2019エラーは出ないし実行もできる謎)。

もっと謎なのが、この問題が起こるクラスと起こらないクラスがあり、クラス名は違えど全く同様の記述でも起きるときと起こらないときがありますので謎は深まるばかりです。

また、シングルトンにしているクラス名は以下のようにdefineで定義したマクロを使用するようになっています。

[code]

    #define SINGLETON_CLASS(T) class T
    
[/code]

このマクロを使用せずclass Hogeとした場合は正常に動作しました。  
しかし諸事情によりこの仕様は必ずしなければならず、class Hogeと書けばよいでは済みません。というか、単にclass
Tに置き換えているだけなのになぜ問題が起きたりしたりしなかったりするのかも謎です。

題目の解決策としてクラスビュー(クラスダイアグラム)を使用してみましたが、問題の箇所がクラスビューに無いので確認が出来ていません。

【今まで試した解決策と結果】  
・プロジェクト丸々作り直し : 失敗  
・suoファイルの削除->再生成 : 失敗  
・関数の順番を変える : 失敗(結局public:次行のみ正常動作)  
・クラス名を変える : 失敗

上記諸々の事情があり、題目に至った次第です。  
よろしくお願いいたします。

* * *

@sayuri さん「現象が再現する範囲で可能な限り簡素化したコードを提示してもらえませんか」に対するコード提示

[code]

    //Hoge.h
    #define DEFINETEST(T) class T
    DEFINETEST(Hoge)
    {
        template <typename T>
        class HogeTemplate
        {
            //略
        };
    public:
        void TestFunc1();//この行は正常に関数定義を見る
        void TestFunc2();//この行以降では関数定義を見つけられない
    };
    //Hoge.cppはTestFunc1とTestFunc2関数しかないものとする
    
[/code]


CC BY-SA 3.0
2017-02-20T19:18:40.663
32821
2017-02-27T04:27:05.530
2017-02-25T04:31:22.693
2808
20642
question
c++ visual-studio
Visual Studio 2015でcppがどのヘッダーを見ているか確認・変更する方法はありますか


F12で定義への移動に失敗するにもかかわらず、コンパイルには成功する点ですが、

>
[code]

>     #define SINGLETON_CLASS(T) class T
>  
[/code]

このコーディング規約が原因と思われます。コンパイラーはソースコードを忠実に解析しますが、IDEは解析速度とのバランスを考えて一部の解析を省略します。

[code]

    #define SINGLETON_CLASS class
    
[/code]

とコーディング規約を改訂するか、それが難しいのであればVisual Studio以外のエディタの使用を検討されてみてはどうでしょうか。

* * *

現象を確認できました。やはり指摘した通り、IDEが解析を端折っているだけです。

[code]

    // 質問の状況
    #define SINGLETON_CLASS(T) class T
    SINGLETON_CLASS(A) {};
    
    // 回答１ … 解決せず
    #define SINGLETON_CLASS class
    SINGLETON_CLASS A {};
    
    // 回答２ … 解析可能
    #define SINGLETON
    SINGLETON class A {};
    
[/code]

辺りにコーディング規約を改定してください（可能であれば）。できないのであれば諦めるか他のエディタを使用するといいでしょう。


CC BY-SA 3.0
2017-02-20T21:29:09.360
32822
2017-02-24T13:26:07.220
2017-02-24T13:26:07.220
4236
4236
32821
answer


まず印象としては、対象マクロが原因であると特定できる場合、  
省略しますが、それを排除するのが合理的であるとする理由は多数見つかります。  
症状についてですが、

1.クラスビューもインテリセンスも同じシンボルDB(pdb)を参照していると予測できるので、同じ結果になるでしょう。

2.経験上、特に#defineマクロについては「定義へ移動」等が苦手なようだという感想を持っています。同一であればどこに書いてもOKですし。

どのヘッダーを見ているか知りたいということに関しては、

3.開示したいヘッダーファイルの行、例えば  
#include "foo.h"
等の行で右クリックし、表示されるコンテキストメニューから「ドキュメント"foo.h"を開く」を選択すると、インクルードパスにてらした該当ファイルが開きます。
これを「名前を付けて保管」しようとすれば、ファイルのロケーションがわかります。

もし可能であれば、

4.この不自然なマクロの意味がうまく推察できなかったのですが、typedef、template、等で置き換えられるなら、その方がC++言語的には自然です。  
個人的には、その言語の本質的な識別子を置換するのには強い違和感を持ちます(デバッグ用は許容しますが)。


CC BY-SA 3.0
2017-02-21T02:28:47.913
32827
2017-02-21T02:28:47.913
3793
32821
answer


コメントより引用：

> 「LINL2019エラーは出ないし実行もできる」とありますが、プログラム動作としては期待通りコンパイル～リンク～実行でき‌​るが、IDE(Visual
> Studio)のインテリセンスがエラーを報告するという質問趣旨なのでしょうか？  
>  はい。期待通りコンパイル～リンク～実行でき‌ますが、「関数定義が見つかりません」と、該当箇所に緑の波線が表示されま‌​す。

短い回答：IntelliSenseは完全なC++コンパイラではありません。IntelliSenseのエラーは単に無視するか、Visual
Studioエディタ利用を諦めてください。

* * *

前提として、Visual
StudioのC++コンパイラ(cl.exe)とIntelliSenseは独立した処理系です。片方がエラーを報告してくる状況でも、もう一方では問題無いというケースが存在します。質問中コードのように複雑なマクロを展開する場合は、IntelliSenseは役に立たなくなるケースが多いと思います。

正直お勧めはしませんが、マクロ`__INTELLISENSE__`を用いればIntelliSense処理中なのか、通常のC++コンパイル処理なのかを判別できます。

[code]

    #define DEFINETEST(T) class T
    
    #ifdef __INTELLISENSE__
    class Hoge
    #else
    DEFINETEST(Hoge)
    #endif
    {
       //...
    };
    
[/code]

Visual C++ Team Blog記事 [Troubleshooting Tips for IntelliSense
Slowness](https://blogs.msdn.microsoft.com/vcblog/2011/03/29/troubleshooting-
tips-for-intellisense-slowness/) も参照ください：

> **The IntelliSense compiler is not the build compiler**  
>  It is important, here, to call out that the IntelliSense compiler is
> different from the build compiler. We have made every effort to give these
> two compilers parity. (For more information about how this works with
> C++/CLI please check this blog post.)
>
> However, there are still differences, and occasionally, a file that compiles
> without error using our build compiler will not compile properly with our
> IntelliSense compiler. Often, this is because the IntelliSense compiler has
> a more strict interpretation of the C++ standard than the build compiler. In
> these cases, you can usually work around this problem by fixing the error
> reported by the IntelliSense compiler. (In most cases, the build compiler
> will happily accept the more-conformant code being required by the
> IntelliSense compiler.)
>
> Additionally, if you are targeting an architecture other than x86, you may
> notice that the IntelliSense compiler is always operating in x86 mode. This
> can produce errors that are very difficult to work around, and while these
> errors will not prevent you from working with most code, they can cause PCH
> generation to fail as mentioned above.
>
> If you are unable to find a code workaround for your problems, there is one
> further stopgap measure that can help: the compiler macro
> `__INTELLISENSE__`, which is only defined when using the IntelliSense
> compiler. You can use this macro to guard code the IntelliSense compiler
> does not understand, or use it to toggle between the build and IntelliSense
> compiler.


CC BY-SA 3.0
2017-02-27T04:27:05.530
32967
2017-02-27T04:27:05.530
49
32821
answer