2017-06-12 7 views
2

find_me関数の戻り値の型を見つけるのと同じトリックを誰かが持っているかどうか知りたいです。呼び出し可能でない関数の結果をdecltypeする方法はありますか?

struct Stuck { 
    Stuck() = delete; 
    Stuck(Stuck&&) = delete; 
    Stuck(const Stuck&) = delete; 
    Stuck& operator=(Stuck&&) = delete; 
    Stuck& operator=(const Stuck&) = delete; 
}; 

double find_me(Stuck); 

int main() { 
    // This obviously don't work 
    decltype(find_me(Stuck{})) test1; 
} 

これは私が試した別のショットです:

template<typename T> 
struct ConvertTo { 
    operator T(); 
} 

int main() { 
    decltype(find_me(ConvertTo<Stuck>{})) test1; 
} 

機能find_meは、多くの多くの時間をオーバーロードし、そして実際に実装されることはありません。関数がこれらの形式を持つときに戻り値の型を見つける方法があるかどうかを知りたいだけです。ポインタや参照を受け取ることが可能であることはわかっていますが、これは私がすでにやっていることですが、この作業をするためのトリックもあるかどうかを知りたいと思います。

もしあれば教えてください。理由を教えてください。

ありがとうございました。

+0

は、それが過負荷になら、ありません。 –

+0

@ T.C。ありがとう。私はその後、リファレンスを使用し続けます。 –

+0

このfind_me関数は、by-valueであろうと参照によるものであろうと、どのような目的を持っていますか? – Brian

答えて

4

これは動作します:

struct Stuck { 
    Stuck() = delete; 
    Stuck(Stuck&&) = delete; 
    Stuck(const Stuck&) = delete; 
    Stuck& operator=(Stuck&&) = delete; 
    Stuck& operator=(const Stuck&) = delete; 
}; 

double find_me(Stuck); 
void find_me(double); 

template <typename Ret> 
Ret get_stuck_return_type(Ret (*)(Stuck)); 

int main() { 
    decltype(get_stuck_return_type(find_me)) test1; 
} 

Coliruリンクを:これはfind_meが過負荷になった場合でも動作しますなぜhttp://coliru.stacked-crooked.com/a/7eca81a13fae9de3

理由は、テンプレート引数控除ということですfind_meの各オーバーロードを試行します。控除がちょうど1つの過負荷で成功した場合は、テンプレートをインスタンス化するために控除が選択されます。

私はこれは純粋に学問的な試行であると考えています。なぜなら、値によって構造化できない型をとる関数が実際の目的を果たせないからです。

+0

はい、この関数には目的があります。私はいくつかの型を別の型にマップするためにそれを使います。この関数は決して実装されません。私はメタプログラミングの文脈でそれを使用します。 –

+2

'find_me'がテンプレートであれば動作しません。 'template void find_me(double、T);'それを殺します。 –

+0

@ T.C。私は同意する、私はこの問題の一般的な解決策はないと思う。 OPは本当に彼のデザイン目標を考え直すべきです。 – Brian

0

std::declvalは、トリックを行います。

decltype(find_me(std::declval<Stuck>())) test1; 
+2

'削除された関数の使用 'Stuck :: Stuck(Stuck &&)' ' –

0

テンプレートのスペシャライゼーションを追加するのはどうですか?

あなたのコード:

template <typename T> 
struct find_me 
{ 
    struct please_add_your_own_find_me {}; 
    using type = please_add_your_own_find_me; 
}; 

クライアントコード:次に

template <> 
struct find_me<Stuck> 
{ 
    using type = double; 
}; 

find_me<Stuck>::value test1; 
関連する問題