2017-02-13 5 views
4

MicrosoftはFold Expressionsをサポートするのが遅く、エミュレートする方法を見つけるのに苦労しているようです。私は以下のカットダウンの例を持っています。 Fold Expressionsをサポートしていないため、Visual Studio 2017でコンパイルできません。 それをエミュレートする方法はありますか?折り畳み式の前にvariadic関数でfold式をエミュレートする方法は?

template<typename... Args> 
void get(weak_ptr<sqlite::database> awdb_, Args&&... args) { 
    (*awdb_.lock() << ... << args); 
} 

答えて

6

expander trickがありました:

T.C.として
template <class... Args> 
void get(weak_ptr<sqlite::database> awdb_, Args&&... args) { 
    if (auto db = awdb_.lock()) { 
     using expander = int[]; 
     (void)expander{0, 
      (void(*db << std::forward<Args>(args)), 0)... 
     }; 
    } 
} 

指摘、これは<<*thisバックを返す以外の何かを、私たちは書くことができれば、必ずしも厳密に等価ではない。

template <class F, class Arg> 
decltype(auto) fold(F&& , Arg&& arg) { 
    return std::forward<Arg>(arg); 
} 

template <class F, class A0, class A1, class... Args> 
decltype(auto) fold(F&& f, A0&& a0, A1&& a1, Args&&... args) { 
    return fold(f, f(a0, a1), std::forward<Args>(args)...); 
} 

template <class... Args> 
void get(weak_ptr<sqlite::database> awdb_, Args&&... args) { 
    if (auto db = awdb_.lock()) { 
     auto lshift = [](auto&& a, auto&& b) -> decltype(auto) { return a << std::forward<decltype(b)>(b); }; 
     fold(lshift, *db, std::forward<Args>(args)...); 
    } 
}  
+0

これは、 '<<'ちょうどしかし、LHSというよりも複雑な何かを返すことを前提としてい、それは厳密に同等ではありません。 –

+1

@ T.C。いい視点ね。回避するのは難しいですが。私が今行ったことより簡単な方法があるはずだと思う。 – Barry

+0

@ T.C。便利なことに、 '+'、 '-'、' * '、'/'、'% '、単項' -'、 '=='、 '!='、 '>'、 '<', '> = '、'! '、'& '、' | '、'^'、' '' '...ではなく、' << 'ではありません。 – Barry

関連する問題