質問を詳しく読むのが面倒な人のために、質問は太字になっています。
これは、この質問のフォローアップです。これは、関数内の静的変数の初期化セマンティクスに関係しています。静的変数は一度初期化する必要があり、それらの内部状態は後で変更される可能性があります-私が(現在)リンクされた質問で行っているように。ただし、問題のコードでは、後で変数の状態を変更する機能は必要ありません。
文字列オブジェクトの内部状態を変更する必要がないため、私の立場を明確にさせてください。このコードは、メタ プログラミング用の特性クラス用であり、const char * const ptr の恩恵を受けるため、理想的にはローカル コストの static const 変数が必要です。私の経験に基づいた推測では、この場合、問題の文字列はリンクローダーによってメモリに最適に配置され、コードはより安全になり、意図したセマンティクスにマップされます。
これは、そのような変数のセマンティクスにつながります。「C++ プログラミング言語第 3 版 -- Stroustrup」には、この問題について (私が見つけた限りでは) 何も言うことがありません。つまり、変数は、スレッドの制御フローが最初にコードに到達したときに 1 回初期化されるということだけです。これにより、次のコードが適切かどうか、またそうでない場合、意図されたセマンティクスは何かを考えるようになります。
#include <iostream>
const char * const GetString(const char * x_in)
{
static const char * const x = x_in;
return x;
}
int main()
{
const char * const temp = GetString("yahoo");
std::cout << temp << std::endl;
const char * const temp2 = GetString("yahoo2");
std::cout << temp2 << std::endl;
}
以下は GCC でコンパイルし、「yahoo」を 2 回出力します。これが私が望むものです-しかし、それは標準に準拠していない可能性があります(これが私がこの質問を投稿する理由です)。"SetString" と "String" の 2 つの関数を使用して、後者が最初の関数に転送されるようにする方がエレガントな場合があります。標準に準拠している場合、誰かがブースト(または他の場所)でのテンプレートの実装を知っていますか?
編集: 2010 年 5 月 11 日
次のマクロを使用して、コンパイル時の情報をエンコードするクラスで上記のゲッター/セッターを生成しています。
#define MACRO_STATIC_SETTING_PTR(name, type) \
static const type const set_##name (const type const name##_in) { \
static const type const name = name##_in; \
return name; \
} \
static const type const name() { \
return set_##name(NULL); \
}
#define MACRO_STATIC_SETTING(name, type) \
static const type set_##name (const type name##_in) { \
static const type name = name##_in; \
return name; \
} \
static const type name() { \
return set_##name(NULL); \
}
これらのマクロは、クラス宣言内に配置されます。例えば:
template<class tag>
class ConfigInstance{
public:
MACRO_STATIC_SETTING_PTR(sqllite3_filename, char *)
};
うまくいけば、これは他の人に役立つでしょう。