私はクラスの状態に依存せず、それを変更しないでいくつかのoperator()
オーバーロードを持つ多くの関数オブジェクトを持つライブラリを書いています。さて、私は自分のコードを多くの古いスタイルのAPIで動作させようとしました(これは無作為な必要性ではなく、実際にこのようなAPIを扱わなければなりませんでした)。過負荷。ある時点では、ポインタ演算子を機能させるにはあまりにも多くの変換が必要であり、理論的には単一の可変変換演算子を書くことができるはずです。ここでは、このような可変引数演算子を実装するクラスがある:あなたが見ることができるようにVariadic関数ポインタ変換
struct foobar
{
template<typename... Args>
using fptr_t = void(*)(Args... args);
template<typename... Args>
operator fptr_t<Args...>() const
{
return [](Args... args) {
// Whatever
};
}
};
が、私は私が持っているすべての関数オブジェクトはステートレスであるため、問題はない変換演算子を実装するためにポインタを機能させるラムダ変換を使用しました。期待の意味で、このコードをコンパイルする問題がない++
int main()
{
void(*foo)(int) = foobar();
void(*bar)(float, double) = foobar();
}
グラムを:目標は、次のようにクラスを使用できるようにしました。しかし、テンプレート置換障害エラーと打ち鳴らす++ rejects it:
main.cpp:21:11: error: no viable conversion from 'foobar' to 'void (*)(int)' void(*foo)(int) = foobar(); ^ ~~~~~~~~ main.cpp:11:5: note: candidate function [with Args = int] operator fptr_t<Args...>() const ^ 1 error generated.
なお打ち鳴らすは++限り何の可変引数テンプレートが関与されていないような変換演算子には問題がありません。 1つのテンプレートパラメータを使用すると、コードのコンパイルに問題はありません。上記のコードは、コンパイラによって受け入れられるか拒否されるべきですか?
私は(HTTPS [この一つとして同じバグ]この思う:// llvm.org/bugs/show_bug.cgi?id=24032)。リンクされたSOの質問もあります。リチャード・スミス[バグを言う](http://stackoverflow.com/questions/31225888/pre-typedefing-a-variadic-function-pointer-argument#comment50471304_31225888)私は彼を信じています:) –
回避方法: 'template演算子F *()'で変換し、関数型であることをsfinaeテストに追加し、特性を使用してargsを抽出し、ヘルパーを使用して解凍し、ヘルパーを使用してポインタに変換しますか? –
Yakk