gpt4 book ai didi

c++ - decltype 不解析嵌套 vector 。如何使用嵌套 vector 的模板?

转载 作者:行者123 更新时间:2023-11-30 01:47:59 25 4
gpt4 key购买 nike

我正在尝试重载 + 运算符来处理嵌套 vector 。我认为该函数会调用自身,直到嵌套 vector 解析为基本类型,但我在编译它时得到了一大堆错误。我定义的 vector 运算适用于基本类型,但不适用于可变数量的嵌套 vector 。唯一适用于嵌套 vector 的操作是 << 运算符。

主要.cpp

#include <iostream>
#include <vector>
#include <algorithm>

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;
};

template<typename T1, typename T2>
auto operator+(const std::vector<T1>& l, const std::vector<T2>& r)
-> std::vector<decltype((l[0] + r[0]))>{
typedef decltype((l[0] + r[0])) type;
std::vector<type> ans;
if(l.size() == std::max(l.size(),r.size()))
std::transform(r.begin(), r.end(), l.begin(), std::back_inserter(ans), std::plus<type>());
else
std::transform(l.begin(), l.end(), r.begin(), std::back_inserter(ans), std::plus<type>());
return ans;
};

int main(){

std::vector<std::vector<int>> vecvec = {{1,2,3},{4,5,6},{7,8,9}};
std::vector<int> vec = {1,2,3};

//Both output statements compile
std::cout << vec << std::endl;
std::cout << vecvec << std::endl;

//Does not compile
vecvec = vecvec + vecvec;

//Does compile
vec = vec + vec;

return 0;
}

现在我无法使用嵌套 vector 进行类型提升。我想我需要 std::plus T1 或 std::plus T2,具体取决于促销规则。

template <typename T1, typename T2>
struct Add : std::plus<T1> { };//<- Here

template <typename T1, typename T2>
struct Add<std::vector<T1>, std::vector<T2>>
{
auto operator()(const std::vector<T1>& l, const std::vector<T2>& r)
-> std::vector<decltype(Add<T1,T2>{}(l[0], r[0]))>
{
using type = decltype(Add<T1,T2>{}(l[0], r[0]));
std::vector<type> ans;

if(l.size() == std::max(l.size(),r.size()))
std::transform(r.begin(), r.end(), l.begin(), std::back_inserter(ans), Add<T1,T2>{});
else
std::transform(l.begin(), l.end(), r.begin(), std::back_inserter(ans), Add<T1,T2>{});
return ans;
};
};

template <typename T1, typename T2>
auto operator+(const std::vector<T1>& lhs, const std::vector<T2>& rhs)
-> decltype(Add<std::vector<T1>, std::vector<T2>>{}(lhs, rhs))
{
return Add<std::vector<T1>, std::vector<T2>>{}(lhs, rhs);
}

我试过了,得到的输出是 2 而不是 2.5。

int main(){
p(int) e = {1};
p(double) q = {1.5};
std::cout << (e + q) << std::endl;
return 0;
}

最佳答案

您遇到的问题与名称查找有关。您正在此处对 operator+ 进行非限定名称查找:

template<typename T1, typename T2>
auto operator+(const std::vector<T1>& l, const std::vector<T2>& r)
-> std::vector<decltype((l[0] + r[0]))> {
^^^^^^^^^^^^^

来自 [basic.scope.pdecl]:

The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any)

并且在该函数中,“完整声明符”包括 trailing-return-type。因此,您的 operator+ 模板在声明符 之后 之前不会在范围内。也就是说,{

另一个问题是 std::plusstd::plus 永远不会找到您的 operator+,因为在定义 std::plus 时它还不存在。

在 C++14 中,最简单的解决方案是删除尾随返回类型(无论如何它都会被正确推导)并用一个简单的 lambda 替换 std::plus:

auto plus = [](const type& lhs, const type& rhs) { return lhs + rhs; };

如果没有 C++14,您必须将所有内容转发给另一个函数,以便名称查找可以成功。您可以为此使用 ADL 技巧,但我认为模板更容易理解。这是一个可行的解决方案:

template <typename T1, typename T2>
struct Add : std::plus<T1> { };

template <typename T1, typename T2>
struct Add<std::vector<T1>, std::vector<T2>>
{
auto operator()(const std::vector<T1>& l, const std::vector<T2>& r)
-> std::vector<decltype(Add<T1,T2>{}(l[0], r[0]))>
{
using type = decltype(Add<T1,T2>{}(l[0], r[0]));
std::vector<type> ans;

if(l.size() == std::max(l.size(),r.size()))
std::transform(r.begin(), r.end(), l.begin(), std::back_inserter(ans), Add<T1,T2>{});
else
std::transform(l.begin(), l.end(), r.begin(), std::back_inserter(ans), Add<T1,T2>{});
return ans;
};
};

template <typename T1, typename T2>
auto operator+(const std::vector<T1>& lhs, const std::vector<T2>& rhs)
-> decltype(Add<std::vector<T1>, std::vector<T2>>{}(lhs, rhs))
{
return Add<std::vector<T1>, std::vector<T2>>{}(lhs, rhs);
}

关于c++ - decltype 不解析嵌套 vector 。如何使用嵌套 vector 的模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30873671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com