私は何かが失敗するようにstatic_assertを使用しようとしています。特定のテンプレート関数を特定の方法でインスタンス化しようとすると、コンパイラエラーが生成されます。私はそれを働かせることができたが、それは本当に醜いだった。これを行う簡単な方法はありますか?static_assert(false)を呼び出す正しい方法は何ですか?
これが私の最初の試みでした。これはまったく機能しませんでした。誰もこの関数を使用しようとしても、常にエラーを生成します。
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
私の2番目の試みです。それは実際に動作します。これを呼び出さないとエラーは発生しません。これを呼び出すと、この行を指し、それをインスタンス化しようとしたコードを指す非常に読みやすいエラーメッセージが表示されます。
template< class T >
void marshal(std::string name, T *value)
{
static_assert(std::is_pod<T>::value && !std::is_pod<T>::value, "You cannot marshal a pointer.");
}
問題は、このコードが最高で醜いということです。それはハックのように見えます。私は次回最適化レベルを変更したり、コンパイラを再コンパイルしたり、くしゃみをしたりするなど、コンパイラはこの2番目のケースが最初のものと同じであることを認識し、両方とも動作を停止することに気付きます。
私がやろうとしていることをするためのより良い方法はありますか?
ここにいくつかの文脈があります。 marshal()のいくつかの異なるバージョンを用意して、さまざまな入力タイプに対応したいと考えています。テンプレートをデフォルトのケースとして使用する1つのバージョンが必要です。 char *以外のポインタを特に許可しない別のものが必要です。
何をしようとするvoid marshal(std::string name, std::string)
{
std::cout<<name<<" is a std::string type."<<std::endl;
}
void marshal(std::string name, char *string)
{
marshal(name, std::string(string));
}
void marshal(std::string name, char const *string)
{
marshal(name, std::string(string));
}
template< class T >
void marshal(std::string name, T value)
{
typedef typename std::enable_if<std::is_pod<T>::value>::type OnlyAllowPOD;
std::cout<<name<<" is a POD type."<<std::endl;
}
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
int main (int argc, char **argv)
{
marshal(“should be pod”, argc);
marshal(“should fail to compile”, argv);
marshal(“should fail to compile”, &argc);
marshal(“should be std::string”, argv[0]);
}
のために1次テンプレートの定義を変更する必要がありますか? – cpplearner
@cpplearner一部の人は、オプションパラメータのenable_ifをテンプレートに隠しています。これは、発信者が誤ってその(偽の)パラメータを埋めることができないため、より良いようです。 –