2011-01-05

constexpr関数とテンプレートについて

Twitter / 妖精闇姫 非実在えつえつしーりつく: @kikairoya http://ideone.c ...
Twitter / 妖精闇姫 非実在えつえつしーりつく: template の行を削るとちゃんと(?)コンパイ ...
Ideone.com | Online C++0x Compiler & Debugging Tool

以下のコードを考える。

int g = 0;
 
template< typename T = void >
constexpr int f()
{
    return g;
}
 
int main()
{
    std::cout << f() << std::endl; // 0
    g = 1;
    std::cout << f() << std::endl; // 1
}

これは、一見すると、constexpr関数で、定数でもないstatic変数gを、constexpr関数の中から扱っているように見える。これはエラーにならない。しかし、テンプレートを外すと、エラーになる。何故ならば――

constexpr関数が、関数テンプレートのとき、テンプレートのインスタンス化の結果、constexpr関数の要件を満たさなくなった場合、その関数はconstexprではなくなる。

――からだ。インスタンス化が、constexprの要件をみたいしていないので、関数fは、通常の関数になる。もちろん、関数呼び出しは、定数式ではなくなる。たとえば、以下のようなコードは、エラーになる。

constexpr int x = f() ; // エラー、constexpr変数は、非定数式で初期化できない

2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. typoったのでやり直し。

    ツイートの捕捉および解説ありがとうございます。
    テンプレート関数の場合は特殊なんですねぇ。


    >通常の間数

    通常の関数

    ReplyDelete

You can use some HTML elements, such as <b>, <i>, <a>, also, some characters need to be entity referenced such as <, > and & Your comment may need to be confirmed by blog author. Your comment will be published under GFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.