2016-03-14 21 views

答えて

27

私は何とかキャストする必要がありますか?

はい、static_castを使用できます。

だからでき

std::transform(s.begin(), s.end(), s.begin(), static_cast<int(*)(int)>(std::toupper));

とはstatic_castはまた、特定のタイプの機能ツーポインタ変換を行うことにより、関数オーバーロードを明確にするために使用されてもよい。

auto f1 = static_cast<int(test::*)()>(&test::error); 
auto f2 = static_cast<void(test::*)(int)>(&test::error); 
+29

親愛なる、それは醜いです。 – cat

+2

私はC++の構文を見るたびに、何かを書こうとする衝動を経験します - 何か - Haskell。 – ApproachingDarknessFish

3

曖昧さを排除するには、static_castを使用する必要があります。

&test::errorは、関数がオーバーロードされているため評価できません。これをautoと記されているものに割り当てているという事実は直ちには関係ありません。

1つの修正は、static_cast<int(test::*)()>(&test::error)またはstatic_cast<void(test::*)(int)>(&test::error)を適切に使用することです。

autoはタイプ控除にあいまいさがなくなるため、autoが動作します。

34

メンバ関数のポインタ型を明示的に指定することができます。

int (test::*f1)() = &test::error; 
void (test::*f2)(int) = &test::error; 
+0

申し訳ありませんが、私のコメントは間違っていました。一を足す。 – Bathsheba

+2

これは、キャストは特に必要ではありません。重要なことは、コンパイラがどのオーバーロードを使用すべきかを明確にすることができることです。 –

+0

私は、typedefを追加することで、もっと読みやすくすることができます: 'error_func = int(test :: *)(); error_func f1 =&test :: error; '。 – Synxis

1

答えはすでに与えられているので、私が目に簡単です解決策を提示します。あなたはキャストを毎回書き出すためにしたくない場合は、このような状況は、マクロのために最適です:あなたは醜い関数へのポインタを読み取るために、インターネットを持っていないとき、ここで

template<class T> 
using test_type_t = T test::*; 
#define TEST_CAST(T, F) static_cast<test_type_t<T>>(&F) 

auto f1 = TEST_CAST(void(int), test::error); 
1

は溶液で-member構文:

auto err1 = [](test& t) { return t.error(); }; 
auto err2 = [](test& t, int x) { return t.error(x); }; 

注意今まであなたがタイプとない関数ポインタとしてクロージャを得ること。同じシグネチャを持つ異なるメンバ関数を配列に格納する場合に便利な関数ポインタが必要な場合は、+here参照)を介して関数ポインタに(標準の)関数ポインタをキャストできます。

現時点では、上記のことから、関数ポインタからメンバポインタへと概念的に何かを行うことができます。もちろん、このようなポインタが必要なルーチンを呼び出すことはできません。そして、それはもっと良いです。

関連する問題