あなたは2つの宣言の間で明確にすることができます宣言された関数のシグネチャを検査することによって行われます。ここでは、パラメータタイプを検査するために必要なテンプレートの基本的な例を示します。これは、簡単に一般化することができ(またはあなたがブーストの機能の特徴を使用することができます)が、これはあなたの特定の問題の解決策を発揮するのに十分である:
#include <iostream>
#include <stddef.h>
#include <type_traits>
// I've declared this just so the example is portable:
struct iconv_t { };
// use_const<decltype(&iconv)>::value will be 'true' if the function is
// declared as taking a char const**, otherwise ::value will be false.
template <typename>
struct use_const;
template <>
struct use_const<size_t(*)(iconv_t, char**, size_t*, char**, size_t*)>
{
enum { value = false };
};
template <>
struct use_const<size_t(*)(iconv_t, char const**, size_t*, char**, size_t*)>
{
enum { value = true };
};
は、ここでの動作を示す例です:
size_t iconv(iconv_t, char**, size_t*, char**, size_t*);
size_t iconv_const(iconv_t, char const**, size_t*, char**, size_t*);
int main()
{
using std::cout;
using std::endl;
cout << "iconv: " << use_const<decltype(&iconv) >::value << endl;
cout << "iconv_const: " << use_const<decltype(&iconv_const)>::value << endl;
}
パラメータ型の修飾を検出できると、を呼び出す2つのラッパー関数を記述できます。つまり、iconv
を引数char const**
で、iconv
をchar**
引数で呼び出すものです。
機能テンプレートの特殊化を避ける必要があるため、クラステンプレートを使用して特殊化を行います。また、invokerのそれぞれを関数テンプレートにして、使用する特殊化のみがインスタンス化されるようにします。コンパイラーが誤った特殊化のコードを生成しようとすると、エラーが発生します。
call_iconv
でこれらの使用法をラップして、iconv
を直接呼び出して簡単に呼び出します。 ;私はうまくいけば、それがどのように動作するか、それをより明確にすることの各部分を明示的にしようとした
template <bool UseConst>
struct iconv_invoker
{
template <typename T>
static size_t invoke(T const&, /* arguments */) { /* etc. */ }
};
template <>
struct iconv_invoker<true>
{
template <typename T>
static size_t invoke(T const&, /* arguments */) { /* etc. */ }
};
size_t call_iconv(/* arguments */)
{
return iconv_invoker<
use_const<decltype(&iconv)>::value
>::invoke(&iconv, /* arguments */);
}
(この後者のロジックをクリーンアップし、一般化することができ、次はこれを書くことができるかを示す一般的なパターンです。)
か? – nims
あなたの最初のための質問の地獄。 :) – Almo
FreeBSDにバグを記録する。 POSIXの['iconv'](http://pubs.opengroup.org/onlinepubs/009695399/functions/iconv.html)の実装では、' inbuf'は非constでなければなりません。 – dreamlax