std :: function:引数の厳密なコンパイル時間検証
-
28-10-2019 - |
質問
事前定義された関数署名を備えた2つのコールバックを保持するクラスを実装したいと思います。
クラスにはテンプレートCTORがあり、std :: bindを使用してSTD :: functionメンバーを作成します。間違った署名の関数が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"
関数引数と返品値を比較するだけで最善だと思います。方法を提案してください。
ありがとうございました。
解決
コンストラクター本体で静的に主張することができます。
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");
所属していません StackOverflow