C++で一般的な方法で何かを実装する方法がちょっと混乱しました。ちょっと複雑なので、私は一歩一歩説明しましょう。テンプレートの引数としてのテンプレート関数
は、このようなコードを考えてみましょう:
void a(int) {
// do something
}
void b(int) {
// something else
}
void function1() {
a(123);
a(456);
}
void function2() {
b(123);
b(456);
}
void test() {
function1();
function2();
}
それはそのfunction1
顕著に容易だとfunction2
は異なる部分のみが内部関数であることで、同じことを行います。
したがって、コードの冗長性を避けるため、function
を汎用化したいと考えています。私は関数ポインタやテンプレートを使ってそれを行うことができます。今私は後者を選んでみましょう。 私の考えは、コンパイラが確実に関数をインライン化することができるからです。正しいのですか?関数ポインタを使ってコンパイラがインラインで呼び出しを行うことはできますか?これは副疑問です。元のポイントに
OK、...テンプレートとソリューション:
void a(int) {
// do something
}
void b(int) {
// something else
}
template<void (*param)(int) >
void function() {
param(123);
param(456);
}
void test() {
function<a>();
function<b>();
}
すべてOK。しかし、私は問題に遭遇しています:a
とb
がジェネリック自身であれば、それでもやってもいいですか?
template<typename T>
void a(T t) {
// do something
}
template<typename T>
void b(T t) {
// something else
}
template<...param...> // ???
void function() {
param<SomeType>(someobj);
param<AnotherType>(someotherobj);
}
void test() {
function<a>();
function<b>();
}
私は、テンプレートパラメータは、のいずれかであることを知っている:
- タイプ、
- テンプレートの種類、
- 型の値。
私の状況をカバーするものはありません。私の主な質問は以下の通りです:最後の例でfunction()
を定義するとどうすれば解決できますか?
(はい、この正確なケースでは、関数ポインタは回避策であるようですが、インライン化することもできますが、この問題の一般的な解決策を探しています)。
これがなぜ落とされたのかは正確には分かりません。それは完全に満足できるものではありませんが、問題を解決します。 –
要約:コールをインライン化することを可能にする唯一のソリューションは、関数をファンクタに置き換えることです。少し扱いにくいけど、まったく受け入れられると思う。ありがとう! – Kos
しかし、私はあなたがバイ・アドレス呼び出しをインライン化することはできないと言った後、私は非常に驚いていると認めます...アドレスがコンパイル時に特定の関数のアドレスと等しいと判断できる場合、コンパイラは十分にスマートになる。 :)奇妙な... – Kos