2017-11-08 1 views
1

私は以下のMWEを持っています。 2つのメンバー(整数と文字列)を持つクラスが含まれています。関数firstを使用して、クラスのオブジェクトを作成し、そのオブジェクトへのポインタを返します。 second_intsecond_strでは、2人のメンバーを出力します。Rcpp:テンプレート関数の作成

second_intsecond_strが多かれ少なかれ同じ機能を持っているとすれば、それらをテンプレート化することは明らかです。これは私のMWEを与えられたRcpp内で行うことが可能ですか?

class C{ 
public: 
    std::vector<int> i_vec; 
    std::vector<std::string> s_vec; 

    C(){ 
    i_vec.push_back(0); 
    s_vec.push_back("R"); 
    } 
}; 

// [[Rcpp::export]] 
XPtr<C> first() 
{ 
    XPtr<C> p(new C, true); 
    return(p); 
} 

// [[Rcpp::export]] 
void second_int(XPtr<C> p) 
{ 
    Rcout << p->i_vec[0] << "\n"; 
} 

// [[Rcpp::export]] 
void second_str(XPtr<C> p) 
{ 
    Rcout << p->s_vec[0] << "\n"; 
} 
+0

機能は、外部から...似て見えるように、内部的に、彼らは非常に異なる2つのことをやっています。これらを1つの関数にマージしようとすると、間違っています。私はあなたがそれらをそのままにしておくか、または彼らが操作するベクトル型の関数をパラメータ化することをお勧めします。すなわち、Cへのポインタではないベクトルを渡す – smac89

+0

なぜそれらをテンプレートにしたいですか?それらの入力/出力は同一である: 'void'と' XPtr'。それらは2つの異なる機能です。このコードは正しいと思います。 – JRR

答えて

2

ここでテンプレートを直接使用することはできませんが、私はあなたが望むと思うものを達成するために使用することができます。あなたが書かれたものと、それがのように見えるものを考えて、のようなものを書いてみましょう。

// [[Rcpp::export]] 
void second_int(XPtr<C> p) 
{ 
    Rcout << p->i_vec[0] << "\n"; 
} 

// [[Rcpp::export]] 
void second_str(XPtr<C> p) 
{ 
    Rcout << p->s_vec[0] << "\n"; 
} 

、あなたはこれがある(これは有効なC++ではありません)希望するもの:

あなたは持っている

// [[Rcpp::export]] 
template< membername member_to_extract > 
void second(XPtr<C> p) 
{ 
    Rcout << p->member_to_extract[0] << "\n"; 
} 

/** 
* we would like to call it like this: 
* second<i_vec>(p) (to get the int value) 
* second<s_vec>(p) (to get the str value) 
*/ 

しないのはなぜこの作品?さて、http://en.cppreference.com/w/cpp/language/template_parametersをチェックすると、変数名をテンプレートパラメータとして渡すことはできません。だからこのアプローチは失敗する運命です。 (注:!あなたが探している解決策になることがあり、このためにあなたでき使用マクロ、)

しかし、あなたの関数の引数ながら型を返すが同じで、彼らの行動を単独に基づいて決定されますあなたが扱いたいタイプ。すでにテンプレート化されたコンテキストでこれらの関数を使用する場合は、2番目と2番目のインタフェースを取得することが望ましいでしょう。

レスキューテンプレート特化!

// generic template. We need something that fails to compile 
// so that second<int> and second<std::string> are the only 
// specializations the compiler will allow us to use. 
template< typename T > 
void second(XPtr<C> p) 
{ 
    static_assert(false, "second can't be used with this type."); 
} 

template< > 
void second<int>(XPtr<C> p) 
{ 
    Rcout << p->i_vec[0] << "\n"; 
} 

template< > 
void second<std::string>(XPtr<C> p) 
{ 
    Rcout << p->s_vec[0] << "\n"; 
} 

私はこれがあなたが望むものだと思いますか?あなたのプラットフォームがラインバッファではない場合は、フラッシュを強制するので、おそらくは "\ n"の代わりにstd :: endlを使いたいかもしれないことに注意してください。

EDIT:一部専門 - >テンプレートの特殊

関連する問題