我一直在試用Curiously Recurring Template Pattern以獲得一個通用的單參數仿函數,並且有兩個實現:一個使用模板模板參數,第二個嘗試訪問在接口類中派生的Functor :: type。在後者的示例中,編譯器(gcc 5.4.0)報告CTRP派生類中沒有類型命名爲'type'
錯誤:無類型命名爲 '結構立方<雙>'
template<class T, template<class> class Functor>
class FunctorInterface_1 {
private:
const Functor<T> &f_cref;
public:
FunctorInterface_1() : f_cref(static_cast<const Functor<T>&>(*this)) {}
T operator() (T val) const { return f_cref(val); }
}; // FunctorInterface_1 (works)
template<class Functor>
class FunctorInterface_2 {
private:
const Functor &f_cref;
public:
using Ftype = typename Functor::type;
FunctorInterface_2() : f_cref(static_cast<const Functor&>(*this)) {}
Ftype operator() (Ftype val) const { return f_cref(val); }
}; // FunctorInterface_2 (no type in Functor!)
I '類型'然後嘗試在以下兩個類的main()中使用T = double進行編譯:
template<class T>
struct Square : public FunctorInterface_1<T,Square> {
T operator()(T val) const { return val*val; }
}; // Square
template<class T>
struct Cube : public FunctorInterface_2<Cube<T>> {
using type = T;
T operator() (T val) const { return val*val*val; }
}; // Cube
可以將FunctorInterface_2/Cube示例修改爲可用,或者 在第一個示例中是否需要在T上將接口類模板化爲 ?謝謝!
編輯:使用gcc -std = C++ 14,但我可以通過在FunctorInterface_1 :: operator()中使用自動返回和參數類型來獲得第二個示例來編譯並運行 ,類型不是C++ 14標準的一部分。
編輯2:嗯,我感覺有點厚。我只是意識到我可以在一個新參數上爲FunctorInterface_1 :: operator()創建模板,然而,對於我所考慮的應用程序,我真的很希望我的基類能夠訪問派生類中定義的類型。
這是一個相當花哨的替代方法,直接將此類型作爲OP在第一次執行時作爲模板參數提供。我必須提到,如果type通過trait傳遞,那麼派生類也必須從trait中提取它,也就是'using type = T;'應該是'使用type = FunctorTraits> :: type;'。否則,這種實施是非常脆弱的。 –
VTT
Traits方法對保持我的接口不可知是有吸引力的,但是,它似乎會增加開發派生類型的負擔。我想到的應用程序涉及複雜的抽象矢量操作,它將有一些用於索引的OrdinalType和用於包含在其中的數據的一些ElementType。我也在探索一種純粹的特質方法(而不是繼承),但是我們正在探索我們目前實現的虛擬繼承(copius動態向下轉換!)方法的優點。 –
@VTT,特徵方法還有其他好處。例如。 Functor類不需要是類模板,就像OP使用的第一種方法一樣。我同意第二點。然而,OP可能根本不需要它。 –