0

MSVS 2010 で一部のコードをコンパイルするときに問題が発生し、C2678 エラーが発生します。ここでそのエラーの説明を見つけました:

http://msdn.microsoft.com/en-us/library/ys0bw32s(v=vs.100).aspx

しかし、「ネイティブメンバーを固定する」という意味がわかりません。

誰か説明できますか?

そのエラーを生成したコードの一部を次に示します。

#pragma once

#include <functional>
#include <vector>
#include <memory.h>

template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
class CCallbackContainer
{
    typedef std::function<void(param_t)> callback_t;

public:
    struct callbackInfo_t
    {
        callbackCodes_e code;
        callback_t callback;
        param_t param;
        size_t countdownToAutoDelete;
    };

    CCallbackContainer() {};
    ~CCallbackContainer() {};

    typedef std::function<void(param_t)> callback_t;
    typedef callbackInfo_t HANDLE;

    std::vector<callbackInfo_t> m_Callbacks[endOfCodes];
    void callbackCall(callbackInfo_t const & callbackInfo);

public:
    inline bool validCode(callbackCodes_e code) { return code < endOfCodes; }

    HANDLE callbackSet(callbackCodes_e code, callback_t callback, DWORD param, size_t countdownToAutoDelete = 1);
    void callbackClear(HANDLE callbackToRemove);
    void callbackCall(callbackCodes_e code)
    {
        auto callbackList = m_Callbacks[code];
        for(auto i: callbackList)
        {
            i->callback(i->param);
        }
        for_each(auto i = callbackList.rbegin(); i != callbackList.rend(); ++i)
        {
            if (--(i->countdownToAutoDelete) < 1)
            {
                callbackList.erase(i);
            }
        }
    }
};

// template implimentation has to be in header file
template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
typename CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::HANDLE // return
    CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::callbackSet // function name
        (callbackCodes_e code, callback_t callback, DWORD param, size_t countdownToAutoDelete) // parameters
{
    ASSERT(validCode(code));
    callbackInfo_t callbackInfo = { code, callback, param, countdownToAutoDelete };
    ASSERT(std::find(m_Callbacks[code].begin(), m_Callbacks[code].end(), callback) == m_Callbacks[code].end());
    m_Callbacks[code].push_back(callbackInfo);
    return callbackInfo;
}

template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
void // return type
    CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::callbackClear // function name
        (typename CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::HANDLE callbackToRemove) // parameters
{
    callbackCodes_e code = callbackToRemove.code;
    ASSERT(validCode(code));
    auto iCallbackInfo = std::find(m_Callbacks[code].begin(), m_Callbacks[code].end(), callbackToRemove);
    ASSERT(iCallbackInfo == m_Callbacks[code].end());
    m_Callbacks[code].erase(iCallbackInfo);
}

template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
void // return type
    CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::callbackCall // function name
        (callbackInfo_t const & callbackInfo) // parameters
{
    callbackInfo.callback(callbackInfo.param);
    if (--callbackInfo.countdownToAutoDelete < 1)
    {
        callbackClear(callbackInfo);
    }
}

template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
void // return type
    CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::callbackCall // function name
        (callbackCodes_e code) // parameters
{
    auto callbackList = m_Callbacks[code];
    for(auto i: callbackList)
    {
        i->callback(i->param);
    }
    for_each(auto i = callbackList.rbegin(); i != callbackList.rend(); ++i)
    {
        if (--(i->countdownToAutoDelete) < 1)
        {
            callbackList.erase(i);
        }
    }
}

ただし、エラーは実際にはアルゴリズムの何かによって生成されました。

14>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(41): エラー C2678: バイナリ '==': タイプ 'CCallbackContainer:: の左側のオペランドを取る演算子が見つかりません:: callbackInfo_t' (または受け入れ可能な変換がない)
14>と
14>[
14> callbackCodes_t=CBalloonHelp::callbackCodes_t,
14> endOfCodes=eCallbackEnd,
14> param_t=DWORD
14> ]
14> 「組み込み C++ operator==(std::_Bool_type, std::_Bool_type)」の可能性があります
14> c:\program files (x86)\microsoft visual studio 10.0\vc\include\functional(277): または 'bool std::tr1::operator ==(std::tr1::_Unutterable,const std:: tr1::function &)' [引数依存ルックアップを使用して発見]
14>と
14>[
14> param_t=DWORD,
14> _Fty=ボイド (DWORD)
14> ]
14> c:\projects\cv-7646\og50\include\gxcoll.h(67): or 'BOOL operator ==(const GCNDX &,const GCNDX &)' [引数依存ルックアップで発見]
14> c:\program files (x86)\microsoft sdks\windows\v7.0a\include\guiddef.h(192): または 'int operator ==(const GUID &,const GUID &)' [引数を使用して検出-依存ルックアップ]

// ... 署名に一致しなかった他の operator==() テスト。

callbackInfo_t のデフォルトの operator==() に問題があるように見えますが、その理由はわかりません。

4

1 に答える 1

3

ピン留めは、C++.NET で使用される用語です。これは、参照されたクラス ( で宣言されたものref class) がネイティブ メンバー変数にアクセスする必要がある場合に使用されます管理された参照はメモリ内で移動できるため、固定する必要がありますが、ネイティブ ポインターは固定された場所に留まる必要があります。メンバー変数を固定すると、ネイティブ ポインターが取得され、すべて正常に動作します。オブジェクトの固定が解除されると、再び移動可能になります。詳細については、pin_ptr<>テンプレートを検索してください。

しかし、あなたのコードには何もないref classので、固定コメントは誤解を招くだけです!

operator==()あなたの問題は、構造体に を提供しなかったことですcallback_t!

これを行うか、状況により適したものを実行してください。

 struct callbackInfo_t
    {
        callbackCodes_e code;
        callback_t callback;
        param_t param;
        size_t countdownToAutoDelete;

        bool operator==(const callbackInfo_t &o) const
        {
           return code == o.code && callback == o.callback &&
                  param == o.param && countdownToAutoDelete == o.countdownToAutoDelete;
        }
    };

ただし、明らかに、比較するメンバー変数も比較可能でなければならないことに注意してください。そうしないと、コードは同様のメッセージで再び失敗します。

于 2013-09-19T22:51:58.510 に答える