4

定義済みの関数シグネチャを持つ 2 つのコールバックを保持するクラスを実装したいと思います。

このクラスには、std::bind を使用して std::function メンバーを作成するテンプレート化された ctor があります。間違った署名の関数が ctor に渡されると、コンパイラ (g++ 4.6) が文句を言うだろうと思っていました。ただし、コンパイラは次を受け入れます。

    callback c1(i, &test::func_a, &test::func_a);

なぜそうなるのか理解できます。static_assert の適切な条件を構築しようとしましたが、成功しませんでした。

これを防ぐためにコンパイル時エラーを発生させるにはどうすればよいですか?

#include <functional>

using namespace std::placeholders;

class callback {
public:
    typedef std::function<bool(const int&)>     type_a;
    typedef std::function<bool(int&)>       type_b;

    template <class O, typename CA, typename CB>
        callback(O inst, CA ca, CB cb)
        : 
        m_ca(std::bind(ca, inst, _1)),
        m_cb(std::bind(cb, inst, _1))
        { }

private:
    type_a  m_ca;
    type_b  m_cb;
};


class test {
public:
    bool func_a(const int& arg) { return true; }
    bool func_b(int& arg) { arg = 10; return true; }
};

int main()
{
    test i;
    callback c(i, &test::func_a, &test::func_b);

// Both should fail at compile time

    callback c1(i, &test::func_a, &test::func_a);
//  callback c2(i, &test::func_b, &test::func_b);

    return 0;
}

更新:訪問者からの回答は、私の最初の問題を解決します。残念ながら、解決すべき関連するケースがたくさんあります。これらは、次のコード ( http://ideone.com/P32sU )で示されています。

class test {
public:
    virtual bool func_a(const int& arg) { return true; }
    virtual bool func_b(int& arg) { arg = 10; return true; }
};

class test_d : public test {
public:
    virtual bool func_b(int& arg) { arg = 20; return true; }
};

int main()
{
    test_d i;
    callback c(i, &test_d::func_a, &test_d::func_b);
    return 0;
}

関数のシグネチャは有効ですが、訪問者によって提案された static_assert がこの場合にトリガーされます。

prog.cpp: In constructor 'callback::callback(O, CA, CB) [with O = test_d, CA = bool (test::*)(const int&), CB = bool (test_d::*)(int&)]':
prog.cpp:41:51:   instantiated from here
prog.cpp:17:12: error: static assertion failed: "First function type incorrect"

関数の引数と戻り値を比較するだけでよいと思います。方法を提案してください。

ありがとうございました。

4

1 に答える 1

1

コンストラクタ本体で静的にアサートできます。

static_assert(std::is_same<CA, bool(O::*)(const int&)>::value, "First function type incorrect");
static_assert(std::is_same<CB, bool(O::*)(int&)>::value, "Second function type incorrect");

参照: http://ideone.com/u0z24

于 2011-12-06T10:29:04.863 に答える