簡體   English   中英

如何為創建靜態和動態尺寸矢量提供通用接口?

[英]How to provide a common interface for creation of static and dynamic size vectors?

我目前有很多代碼可用於動態尺寸矢量 (例如std::vectorEigen::VectorXd等),我希望它也可用於靜態尺寸矢量 (例如std::arrayEigen::Vector3d ,...)。 我的代碼相對於TVector是模板化的,它假定TVector sizeoperator[] 但是最大的問題是建築

在構造靜態和動態矢量時,沒有共同點。 我決定用以下假設函數替換對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;
}

IntegerConstructibleNotIntegerConstructible是它們只要模板參數可(或不能)來構造定義的別名模板。 定義時, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM