最初に呼び出されたとき (または最初の n 回) に 1 つの実行パスを取り、複数回 (n 回以上) 呼び出された場合に別の実行パスを取ることができるテンプレート メタ構造を作成することは可能ですか?
4 に答える
いいえ。テンプレートはコンパイル時にのみ評価されます。
問題は、実行時に発生すること (実行パス) に関するものです。
この構造をコードで構築することは非常に可能であるはずですが、これはテンプレート メタ構造ではありません (ただし、テンプレート メタ プログラムの一部にすることはできますが、テストを実行するコードは実行時コード (つまり、通常のコード) になります)。 )))。
テンプレートで達成できるのは、テンプレートの特殊化を使用したこの例のように、コンパイル時のパスの決定です。
template <bool whichOne>
class ExecutionExampleImpl;
template <>
class ExecutionExampleImpl<true> {
public:
static void doIt() {
std::cout << "Do it for the first time(s)\n";
}
};
template <>
class ExecutionExampleImpl<false> {
public:
static void doIt() {
std::cout << "Do it for the second time(s)\n";
}
};
template <unsigned execution>
void executionExample()
{
const unsigned ExecutionExampleFirstLimit = 3;
ExecutionExampleImpl<execution <= ExecutionExampleFirstLimit>::doIt();
}
int main() {
executionExample<1>();
executionExample<2>();
executionExample<3>();
executionExample<4>();
executionExample<5>();
executionExample<6>();
}
ただし、実行時の決定を好むと思います。これは、静的ローカル変数で作成できます。
void executionExample()
{
const unsigned ExecutionExampleFirstLimit = 3;
static unsigned executionCounter = 0;
if (executionCounter++ < ExecutionExampleFirstLimit)
{
std::cout << "Do it for the first time(s)\n";
}
else
{
std::cout << "Do it for the second time(s)\n";
}
}
int main() {
for (unsigned int i = 0; i < 6; ++i)
executionExample();
}
この質問は、明らかに無関係な 2 つのことと一致します。テンプレートはコンパイラによってインスタンス化され(実行されません)、必要なインスタンスは実行時に (コンパイラではなく) マシンによって実行されます。
できることは、定数値に応じてインスタンス化が異なるテンプレートを作成することです。そして、それらのインスタンスが再帰的である場合、何をインスタンス化するかを決定する一種の「コンパイル時の実行」があります。
std::conditionalは良いサンプルです。
一般的なケースでは、特定のパスをたどるかどうか、および何回たどるかは、実行時に決定できます。関数呼び出しがif
ステートメントの本体にある場合、1 つの明白な例を挙げるとします。ただし、テンプレート (およびそのパラメーター) に依存する実行フローを指示するための構成は、コンパイル時にこれを認識している必要があります。いいえ、それはできません。