std::is_integral
に応じていくつかのタイプしか受け付けない関数オブジェクトを持つライブラリがあります。私は条件が失敗したときにstd::is_invocable
をfalse
に返すようにしたいが、ユーザーが関数オブジェクトのインスタンスを呼び出そうとしたときにもエラーメッセージstatic_assert
が欲しい。このような実装ではstatic_assertとstd :: is_invocableのベストを得る
struct function
{
template<typename Iterator>
auto operator()(Iterator first, Iterator last) const
-> std::enable_if_t<std::is_integral_v<
typename std::iterator_traits<Iterator>::value_type
>>
{ /* something */ }
};
SFINAE条件が満たされないときstd::is_invocable
は予想通りstd::false_type
ですが、彼らは呼び出ししようとすると、ユーザーが醜いSFINAEエラーメッセージが発生します。ここに私は現在持っている関数オブジェクトの簡略化した例でありますSFINAE条件を満たさないパラメータを持つ関数オブジェクト。
struct function
{
template<typename Iterator>
auto operator()(Iterator first, Iterator last) const
-> void
{
static_assert(std::is_integral_v<typename std::iterator_traits<Iterator>::value_type>,
"function can only be called with a collection of integers");
/* something */
}
};
、ユーザーがオリジナルのSFINAE条件が満たされていないフレンドリーエラーメッセージを得るが、かどうかを尋ねられたときstd::is_invocable
はstd::true_type
です:
より良いエラーメッセージを取得するには、私の代わりに、以下のソリューションを試してみましたfunction
インスタンスは、std::is_integral
を満たさないタイプを処理できます。
私はいくつかのトリックやdecltype(auto)
を含むバリエーション、if constexpr
や他のメカニズムを試してみましたが、エラーメッセージが素晴らしく、どこfunction
が正しくないタイプで呼び出すことができるかどうかを尋ねるときstd::is_invocable
が期待std::false_type
に対応したクラスを取得できませんでした。
私はここで何が欠けていますか? std::is_invocable
とユーザーフレンドリーなエラーメッセージの両方を得る方法はありますか?
私は最近これについてブログの投稿を書いています。https://gracicot.github.io/tricks/2017/07/01/deleted-function-diagnostic.html –