[英]How to provide a common interface for creation of static and dynamic size vectors?
我目前有很多代碼可用於動態尺寸矢量 (例如std::vector
, Eigen::VectorXd
等),我希望它也可用於靜態尺寸矢量 (例如std::array
, Eigen::Vector3d
,...)。 我的代碼相對於TVector
是模板化的,它假定TVector
size
和operator[]
。 但是最大的問題是建築 。
在構造靜態和動態矢量時,沒有共同點。 我決定用以下假設函數替換對TVector
構造函數的所有調用:
template <typename TVector>
TVector createVector(std::size_t sizeAtInitialization)
{
if (TVector has constructor taking an integral type)
return TVector(sizeAtInitialization);
else
return TVector(); // sizeAtInitialization ignored
}
這樣對createVector<TVector>
的通用調用將變為createVector<std::vector<double>>(3)
或createVector<std::array<double, 3>>(3)
。
std :: is_default_constructible在這里對我沒有幫助,因為兩種向量類型都是默認可構造的。
但是,我不確定這種事情是否可能發生。
我研究了靜若 這里和成員函數檢測 在這里 。 一切似乎都極其復雜,並且由於static_if
使用的lambda必須返回中間結果(必須已經構造),因此我不確定它在任何地方都有效。
您可以將std::is_constructible
與一些sfinae和std::enable_if
一起使用
using namespace std;
template <class T>
using IntegerConstructible =
typename enable_if<is_constructible<T, int>::value, T>::type;
template <class T>
using NotIntegerConstructible =
typename enable_if<!is_constructible<T, int>::value, T>::type;
template<class T>
auto createVector(int size)
-> IntegerConstructible<T> {
return {size};
}
template<class T>
auto createVector(int size)
-> NotIntegerConstructible<T>{
return {};
}
int main(){
auto x = createVector<std::vector<int>>(3);
auto y = createVector<std::array<int,3>>(3);
return 0;
}
IntegerConstructible
和NotIntegerConstructible
是它們只要模板參數可(或不能)來構造定義的別名模板。 定義時, IntegerConstructible<T> = T
因此,兩個createVector
函數中只有一個具有有效的返回類型,而另一個不能被調用。 這使編譯器可以選擇正確的重載。
我喜歡SFINAE(對於Tim來說為+1),但我認為對於這種類型的問題,標簽分配更加清晰
#include <array>
#include <vector>
#include <iostream>
#include <type_traits>
template <typename T>
T cVH (int size, std::true_type const &)
{ std::cout << "with size" << std::endl; return { size }; }
template <typename T>
T cVH (int, std::false_type const &)
{ std::cout << "without size" << std::endl; return { }; }
template <typename T>
T createVector (int size)
{ return cVH<T>(size, typename std::is_constructible<T, int>::type{}); }
int main()
{
auto x = createVector<std::vector<int>>(3); // print "with size"
auto y = createVector<std::array<int,3>>(3); // print "without size"
}
-編輯-
如果沒有一種類型特征可以為所有類型選擇正確的值,則可以自己創建一個,如下所示( struct withSize
)
#include <array>
#include <vector>
#include <iostream>
#include <type_traits>
template <typename>
struct withSize;
template <typename T>
struct withSize<std::vector<T>>
{ using type = std::true_type; };
template <typename T, std::size_t N>
struct withSize<std::array<T, N>>
{ using type = std::false_type; };
// others specializations of withSize for Eigen::Vector3d, Eigen::Matrix, etc.
template <typename T>
T cVH (int size, std::true_type const &)
{ std::cout << "with size" << std::endl; return { size }; }
template <typename T>
T cVH (int, std::false_type const &)
{ std::cout << "without size" << std::endl; return { }; }
template <typename T>
T createVector (int size)
{ return cVH<T>(size, typename withSize<T>::type{}); }
int main()
{
auto x = createVector<std::vector<int>>(3); // print "with size"
auto y = createVector<std::array<int,3>>(3); // print "without size"
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.