2

で関数型を引き離す離れthis questionピッククラステンプレートを使用して関数型への答えは:私はここで行われていたものを研究したよう特殊機能

template <typename T> 
struct function_args {}; 

template <typename R, typename... Args> 
struct function_args<R(Args...)> { 
    using type = tuple<Args...>; 
}; 

template <typename T> 
using decltypeargs = typename function_args<T>::type; 

私はfunction_argsを書き換えてみました。私はdecltypeargsテンプレートの必要性を排除するために関数を使用してこれを実行しようとしました。しかし、私自身は、不適切な構文に陥っ見つかり:

template <typename T> 
tuple<> myTry(); 

template <typename Ret, typename... Args> 
tuple<Args...> myTry<Ret(Args...)>(); 

私の希望はdecltypeargs<decltype(foo)>を呼び出すために持つのではなくtupleタイプを取得するためにdecltype(myTry<decltype(foo)>())を呼び出すようになっていました。関数宣言でこれを行う方法はありますか?

+0

。しかし、私はあなたが何か他に尋ねたいと思う。私にはあまり明確ではありません。 – Arunmu

+0

@Arunmuあなたが私の質問に答えたように聞こえます。しかし、私は言葉遣いをどのように改善するかについてはっきりしていません。私は関数の戻り値と引数を分離しようとしています。そのためには特殊化を使用する必要があります。私は関数でそれをやりたかったのですが、私はできないように思えます。それはもっと明確ですか? –

+0

あなたがしようとしていることがわかりません。 'myTry()'はそれを使用していないよりもタイピングが簡単です - あなたが解決しようとしている問題は何ですか? – Barry

答えて

2
//------------------------ Machinery: 
#include <tuple> 

template< class Ret, class... Args > 
std::tuple<Args...> m(Ret(Args...)); 

//------------------------- Example: 
#include <iostream> 
#include <typeinfo> 

void foo(double); 

using namespace std; 
auto main() 
    -> int 
{ 
    using Args_tuple = decltype(m(foo)); 
    cout << typeid(Args_tuple).name() << endl; 
} 
+0

それはちょうど私が一緒に、どのように1つの機能の中で行うことができなかったものです。あなたが初めてそれを正しく行うことができるとき、誰が専門性を必要としますか? –

+0

私はここでフォローアップの質問をしました:http://stackoverflow.com/q/38482805/2642059私は 'decltype(m(foo))'メソッドを操作するために展開します。 –

+0

それは解決されたようです。 :) –

1

関数はそれほど特殊化することはできませんが、関数を特殊化する必要はありません。 GCC 6.1.1でテスト:

template <typename T> 
function_args<T> myTry(); 

それとも機能と同じように再実装することができます機能で

#include <iostream> 
#include <tuple> 

template <typename T> struct my_try; 

template <typename Ret, typename... Args> 
struct my_try<Ret(Args...)> { 

    std::tuple<Args...> operator()(); 

}; 

template<typename T> 
auto MyTry() 
{ 
    return my_try<T>()(); 
} 


void foo(int, char); 

int main() 
{ 
    decltype(MyTry<decltype(foo)>()) t; 

    int *a= &std::get<0>(t); 
    char *b= &std::get<1>(t); 

    return 0; 
} 
+0

私は関数でそれを達成すると思います。私は*構造体を関数に置き換えることを望んでいました。 [それはしかし、それは可能ではないように聞こえる](http://stackoverflow.com/questions/38463980/pull-apart-function-type-with-specialized-function#comment64332056_38463980)。たぶんこの代わりに、関数を特殊化することはできないという公式の声明を単に引用することができますか? –

+0

私は、構造体を置き換えることによって何が得られるのかわかりません。それはコンパイルされると、ちょうど0ビットを占めます。 –

+0

あなたは完全に正しいです。関数宣言がより快適になったので、私はそれらを使用しようとしていました。だから答えは、単純に: "あなたはそれを行うことはできません。しかし、「私がそう言ったから」以外の何かを引用して引用することができればいいだろう。 –

3

、あなたはどちらかだけ前から同じ型特性を再利用することができます。あなたは、部分的に関数テンプレートを特化することはできませんが、オーバーロードすることができます:あなたは、関数テンプレートと部分的特殊化を行うことはできません

namespace detail { 
    template <class T> struct tag { }; 

    template <class R, class... Args> 
    tag<std::tuple<R, Args...>> myTry(tag<R(Args...)>); 

    template <class R, class C, class... Args> 
    tag<std::tuple<R, Args...>> myTry(tag<R(C::*)(Args...)>);   

    // etc. 
} 

template <typename T> 
auto myTry() { return detail::myTry(detail::tag<T>{}); } 
+0

「タグ」とは何ですか? –

+0

@ Cheersandhth.-Alfそれは彼が部分的な専門分野をハックするために使用しているものです。基本的にこれは私の悪い質問です、明らかに正しい答えは構造体を使用することです、これは単なる創造的な回避策です。 –

+0

'myTry'の2つの定義は、' tag'なしで異なるオーバーロードになります。 –

関連する問題