[解決済み] あるプラットフォームではchar**を受け取り、他のプラットフォームではconst char**を受け取るC++関数を、どのようにして移植的に呼び出すことができますか?
質問
私の Linux (および OS X) マシンでは
iconv()
関数はこのプロトタイプを持っています。
size_t iconv (iconv_t, char **inbuf...
であるのに対し、FreeBSDではこのようになります。
size_t iconv (iconv_t, const char **inbuf...
C++のコードを両方のプラットフォームでビルドしたいのですが、どうすればいいですか?C コンパイラでは
char**
に対して
const char**
パラメータを渡した場合(またはその逆の場合)、通常は単なる警告が表示されますが、C++では致命的なエラーとなります。ですから、もし私が
char**
を渡すと、BSDではコンパイルできません。
const char**
を渡すと、Linux / OS X ではコンパイルできません。どうすれば、プラットフォームを検出しようとすることなく、両方でコンパイルするコードを書くことができるでしょうか?
私が持っていた 1 つの (失敗した) アイデアは、ヘッダーによって提供されるものをオーバーライドするローカル プロトタイプを提供することでした。
void myfunc(void) {
size_t iconv (iconv_t, char **inbuf);
iconv(foo, ptr);
}
これが失敗するのは
iconv
は C リンクを必要とし、また
extern "C"
を関数内に置くことはできません(なぜ?)
私が思いついた最もうまくいくアイデアは、関数ポインタそのものをキャストすることです。
typedef void (*func_t)(iconv_t, const char **);
((func_t)(iconv))(foo, ptr);
というような、他のもっと深刻なエラーを覆い隠してしまう可能性があります。
どのように解決するのですか?
もし、constの問題に目をつぶるだけなら、その区別を曖昧にする、つまり、char**とconst char**を相互運用可能にする変換を使えばよいのです。
template<class T>
class sloppy {};
// convert between T** and const T**
template<class T>
class sloppy<T**>
{
T** t;
public:
sloppy(T** mt) : t(mt) {}
sloppy(const T** mt) : t(const_cast<T**>(mt)) {}
operator T** () const { return t; }
operator const T** () const { return const_cast<const T**>(t); }
};
その後、プログラムの後半で
iconv(c, sloppy<char**>(&in) ,&inlen, &out,&outlen);
sloppy() は
char**
または
const char*
に変換し、それを
char**
または
const char*
のように、iconvの2番目のパラメータが要求するものであれば、何でもかまいません。
UPDATE: const_castを使用するように変更し、as castではなくsloppyを呼び出すようにしました。
関連
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】char*とconst char*の違い?
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み] std::string を const char* または char* に変換する方法
-
[解決済み] 派生クラス関数から親クラス関数を呼び出すには?
-
[解決済み] C言語とC++の両方で有効なコードを、それぞれの言語でコンパイルすると、異なる動作になることがありますか?
-
[解決済み] ベースクラスの仮想関数をオーバーライドしている場合、その関数を呼び出すことはできますか?
-
[解決済み】char * constとconst char *の違いは何ですか?
-
[解決済み] [Solved] 似たようなconstとnon-constのメンバ関数間のコードの重複を取り除くには?
-
[解決済み] C++とC++の関数パラメータとしての'const int'と'int const'の比較
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++