2

GCCでは、printf 指定子をカスタマイズできます。ただし、指定子として文字列クラスを受け入れるように「教える」方法がわかりません%s。私の文字列クラスは、char ポインターに対する単純なラッパーであり、メンバー変数 (char * data) が 1 つだけあり、仮想関数はありません。したがって、通常の代わりにprintfのような関数にそのまま渡しても問題ありませんchar *。問題は、gcc スタティック アナライザーがそうするのを妨げており、const char *警告やエラーを避けるために明示的にキャストする必要があることです。

私のcstringは次のようになります。

class cstring
{
   cstring() : data(NULL){}
   cstring(const char * str) : data(strdup(str)){}
   cstring(const cstring & str) : data(strdup(str.data)){}
   ~cstring()
   {
        free(data);
   }
   ...
   const char * c_str() const
   {
        return data;
   }

private:
   char * data;
};

cstring を使用するコード例:

cstring str("my string");
printf("str: '%s'", str);

GCC では、次のエラーが発生します:
エラー: 自明でないコピー可能型 'class cstring' のオブジェクトを '...' で渡すことはできません
エラー: 形式 '%s' は型 'char*' の引数を期待していますが、引数 1 には型があります'cstring' [-Werror=format]
cc1plus.exe: すべての警告がエラーとして扱われます

4

1 に答える 1

1

C++ 標準では、コンパイラがこの種のコードをサポートする必要はなく、gcc のすべてのバージョンがサポートしているわけではありません。( https://gcc.gnu.org/onlinedocs/gcc/Conditionally-supported-behavior.htmlは、少なくとも gcc-6.0 が動作することを示唆しています。ここにあるようなクラスで動作するかどうかは未解決の問題です。)

C++11 標準の関連セクションは 5.2.2 セクション 7 です。

指定された引数のパラメータがない場合、引数は、受信関数が va_arg を呼び出して引数の値を取得できるような方法で渡されます...自明でないコピー コンストラクター、自明でないムーブ コンストラクター、または自明でないデストラクタは、対応するパラメーターを持たず、実装定義のセマンティクスで条件付きでサポートされます。

(しかし、明るい面を見てください: を使用する習慣を身につければc_str、少なくとも を使用するときにつまずくことはありませんstd::string。)

于 2012-12-03T00:05:03.300 に答える