我希望能够做这样的事情。
std::vector<std::vector<int>> e = {{ 1 },{ 2 }};
std::vector<std::vector<double>> q = {{1.5},{2.5}};
q = vector_cast<double>(e);
而且还具有vector_cast能够处理任何数量的嵌套 vector 的功能。
这是我的尝试。如果您注释掉标记的行不起作用,则该代码有效。问题是我需要帮助来实现vector_cast函数。
#include <iostream>
#include <vector>
#include <algorithm>
#include <type_traits>
//Prints nested vectors
template<typename T1>
std::ostream& operator<<(std::ostream& stream, std::vector<T1> r){
if(r.size() == 0){
return stream;
}
else{
stream << "(";
for(int i = 0; i < r.size(); i++){
if(i < (r.size() - 1)){
stream << r[i] << ", ";
}
else{
stream << r[i] << ")";
}
}
}
return stream;
};
//Adds nested vectors
template <typename T1, typename T2>
struct vector_common_type : std::common_type<T1, T2> { };
template <typename T1, typename T2>
struct vector_common_type<std::vector<T1>, std::vector<T2>> {
using type = std::vector<typename vector_common_type<T1,T2>::type>;
};
template <typename T1, typename T2,
typename R = std::vector<typename vector_common_type<T1,T2>::type>>
R operator+(const std::vector<T1>& l, const std::vector<T2>& r)
{
R ans;
std::transform(l.begin(),
l.begin() + std::min(l.size(), r.size()),
r.begin(),
std::back_inserter(ans),
[](const T1& lhs, const T2& rhs){ return lhs + rhs; });
return ans;
}
//supposed to cast nested vectors
template <typename T1, typename T2>
struct vector_casting : std::condition<true,T1, T2> { };
template <typename T1, typename T2>
struct vector_casting<std::vector<T1>, std::vector<T2>> {
using type = std::vector<typename vector_casting<T1,T2>::type>;
};
template <typename T1, typename T2,
typename R = std::vector<typename vector_casting<std::vector<T1>,T2>::type>>
R vector_cast(const std::vector<T2>& r){
R l(r.begin(),r.end());
return l;
};
int main(){
std::vector<std::vector<int>> e = {{ 1 },{ 1 }};
std::vector<std::vector<double>> q = {{1.5},{2.5}};
//This works
q = q + q;
//This does not work
q = e;//<- needs cast, but my vector_cast does not work
std::cout << q << std::endl;
return 0;
}
最佳答案
使用 vector 类型检测,您可以执行以下操作:
#include <iostream>
#include <vector>
// is_vector
// =========
namespace Detail {
template<typename T>
struct is_vector_test {
static constexpr bool value = false;
};
template<typename ... Types>
struct is_vector_test<std::vector<Types...>> {
static constexpr bool value = true;
};
}
template<typename T>
struct is_vector : Detail::is_vector_test<typename std::decay<T>::type>
{};
// vector_cast
// ===========
namespace Detail
{
template <typename R, typename U, bool = is_vector<U>::value>
struct vector_cast_implementation;
// Elementary
template <typename R, typename T>
struct vector_cast_implementation<R, T, false>
{
typedef T value_type;
typedef R result_type;
static result_type apply(const value_type& value){
// Simple Conversion
return value;
}
};
// Vectors
template <typename R, typename U>
struct vector_cast_implementation<R, std::vector<U>, true>
{
private:
typedef vector_cast_implementation<R, U> base_cast;
public:
typedef std::vector<typename base_cast::value_type> value_type;
typedef std::vector<typename base_cast::result_type> result_type;
static result_type apply(const value_type& value){
result_type result;
result.reserve(value.size());
for(const auto& element : value)
result.push_back(base_cast::apply(element));
return result;
}
};
}
template <typename R, typename T>
typename Detail::vector_cast_implementation<R, std::vector<T>>::result_type
vector_cast(const std::vector<T>& sequence){
return Detail::vector_cast_implementation<R, std::vector<T>>::apply(sequence);
}
// test
// ====
int main() {
std::vector<std::vector<std::vector<double>>> v3 = {
{{ 0.0 , 0.1, 0.2 },
{ 1.0 , 1.1, 1.2 },
{ 2.0 , 2.1, 2.2 }},
{{ 10.0 , 10.1, 10.2 },
{ 11.0 , 11.1, 11.2 },
{ 12.0 , 12.1, 12.2 }},
};
auto r3 = vector_cast<int>(v3);
for(const std::vector<std::vector<int>>& r2 : r3) {
for(const std::vector<int>& r1 : r2) {
for(int e : r1)
std::cout << e << " ";
}
std::cout << "\n";
}
}
要确定二进制 vector 运算的通用类型R,可以执行以下操作:
// vector_common_type
// ==================
namespace Detail
{
template <typename U,typename V, bool = is_vector<U>::value, bool = is_vector<V>::value>
struct vector_common_type_implementation;
// Elementary
template <typename U, typename V>
struct vector_common_type_implementation<U, V, false, false>
{
typedef typename std::common_type<U, V>::type type;
};
// Vectors
template <typename U, typename V>
struct vector_common_type_implementation<std::vector<U>, std::vector<V>, true, true>
{
typedef typename vector_common_type_implementation<U, V>::type type;
};
}
template <typename U, typename V>
struct vector_common_type;
template <typename U, typename V>
struct vector_common_type<std::vector<U>, std::vector<V>>
: public Detail::vector_common_type_implementation<std::vector<U>, std::vector<V>>
{};
关于c++ - 定义可与可变数量的嵌套 vector 一起使用的 “vector_cast”模板函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30896984/