![](/img/trans.png)
[英]C++ enable_if template class method if it is std::vector<std::vector<Type>>
[英]Using enable_if, in class template method, to check if two function arguments arguments are both std::array or both std::vector
我不是專業的編碼員,如果我的問題顯得幼稚或格式錯誤,我深表歉意。
我試圖讓一個類成員函數在參數中使用std::array
或std::vector
。 具體來說,我傳遞了兩個參數,它們要么都是std::array
要么都是std::vector
。
在嘗試進行上述工作之前,我所擁有的最小設置僅適用於std::vector
參數。 最小設置如下,其中v和p是我希望作為向量或數組傳遞的那些:
// original version
class my_class_A{
// stuf
};
class my_class_B{
// other stuf
};
class I_am_a_class_of_methods{
public:
inline void my_method(const std::vector<my_class_A> &v,
const std::vector<std::array<uint64_t,2> > &p,
const my_class_B &x,
my_class_B &y){
// `v` and `p` are used to modify `x` and store the result in `y`
return;
};
};
我知道我可以用函數重載做我想做的事,但是,我決定用templates
和std::enable_if
來達到預期的結果,迫使我更多地了解它們。 好吧,我確實學到了很多我不知道的東西……但還不夠。 我基本上嘗試過設置特征is_both_array_or_vector
,並且std::enable_if
將檢查模板調用是否與特征匹配。 我嘗試的最后一件事是以下內容,它確實可以編譯,但它僅適用於std::vector
:
// current version
class my_class_A{
// stuf
};
class my_class_B{
// other stuf
};
// set up a type trait to check if both are vector or both are array
template <typename T1, typename T2>
struct is_both_array_or_vector{
enum { value = false };
};
template <typename T1, typename T2, typename A1, typename A2 >
struct is_both_array_or_vector<std::vector<T1, A1>, std::vector<T2, A2> > {
enum { value = true };
};
template <typename T1, typename T2, size_t D>
struct is_both_array_or_vector<std::array<T1, D>, std::array<T2, D> > {
enum { value = true };
};
// conditionally compile with enable_if
class I_am_a_class_of_methods{
public:
template<template<typename,typename> U, template<typename,typename> S,
typename Au, typename As>
typename std::enable_if<is_both_array_or_vector<U<my_class_A, Au>, S<std::array<uint64_t,2>,As> >::value >::type
my_method(const U<my_class_A, Au> &v,
const S<std::array<uint64_t,2>, As> &p,
const my_class_B &x,
my_class_B &y){
// `v` and `p` are used to modify `x` and store the result in `y`
return;
};
};
當我使用來自 main 的std::vector
調用編譯時,一切正常。 這(當然)不能用std::array
調用編譯(編譯器當然會抱怨)。
如果我能讓模板參數As
和Au
能夠被解釋為size_t
,那么模板將找到與std::array
調用的匹配項。 然而,這不可能接縫,因為我可以擁有typename
或size_t
,據我所知,不能同時擁有。 因此我的問題是,在這種情況下我如何讓 enable_if 工作?
更新:正如 Javier 所說,您可以保留一個私有函數模板來處理一般情況,並為您想要的類型重載兩個方法並將它們傳遞給該模板。
class I_am_a_class_of_methods {
private:
template <typename C1, typename C2>
void my_method_priv(const C1& v, const C2& p, const my_class_B& x, my_class_B& y) {
// ...
}
public:
void my_method(const std::vector<my_class_A>& v,
const std::vector<array<uint64_t, 2>>& p,
const my_class_B& x,
my_class_B& y)
{ my_method_priv(v, p, x, y); }
template <size_t N1, size_t N2>
void my_method(const std::array<my_class_A, N1>& v,
const std::array<std::array<uint64_t, 2>, N2>& p,
const my_class_B& x,
my_class_B& y)
{ my_method_priv(v, p, x, y); }
};
我強烈建議在這里使用函數重載作為最佳解決方案。 然而,你說你想嘗試和學習。 既然如此,請允許我展示一種與此類似的方法。
請注意,這有點復雜,因為您需要顯式模板參數,但檢測中並沒有涉及更多的元編程,它至少讓您了解如何在明智的情況下處理這樣的事情 -但在這種情況下,只需使用函數重載。
class I_am_a_class_of_methods
{
template <typename FirstT, typename SecondT>
struct Enable { };
template <typename A1, typename A2>
struct Enable<std::vector<my_class_A, A1>,
std::vector<std::array<uint64_t,2>, A2>>
{
using type = void;
};
template <std::size_t N1, std::size_t N2>
struct Enable<std::array<my_class_A, N1>,
std::array<std::array<uint64_t,2>, N2>>
{
using type = void;
};
public:
template <typename T1, typename T2>
typename Enable<std::decay_t<T1>, std::decay_t<T2>>::type
my_method(T1 const &v, T2 const &p, my_class_B const &x, my_class_B &y)
{
// whatever
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.