gpt4 book ai didi

c++ - 编译器抛出 "ambiguous overload for operator"

转载 作者:行者123 更新时间:2023-12-01 14:52:49 26 4
gpt4 key购买 nike

我正在学习如何使用 std::chrono 并且我想让模板类 Timer 易于使用(在 timer.h 中定义)。测试程序很成功,一切正常,直到我尝试在一个定义了一些模板运算符的程序中使用我的新 Timer,这与 Timer 中使用的运算符相冲突。

内部计时器我必须使用 operator-start_time 类型的两个变量( end_timestd::chrono::time_point )之间,以获得duration包含耗时的变量。

在另一个头文件( algebra.h )中,我实现了二进制文件 operator- 的重载。区分两个 std::vector或两个 std::array ,或者也可以是随 operator[] 提供的用户定义容器和 size()成员函数。

template<typename pointType>
pointType operator-(pointType a, const pointType & b){
for(int i = 0; i < a.size(); ++i){
a[i] = a[i] - b[i];
}
return a;
}

当我尝试同时包含 timer.halgebra.h ,编译器会抛出一个错误,提示“操作符重载的模棱两可”,暗示 algebra.h 中的两个操作符作为可能的候选者。以及在 <chrono> 中实现的那个.

我不明白为什么它是模棱两可的,因为 pointType不能推导出为 std::chrono::time_point因为它没有 operator[]size()成员函数。

附言我尝试了其他方法来解决它,但我只是在测试使用 std::valarray 的程序时感到更加困惑。 .当我同时包含 <valarray> 时和 "algebra.h" ,并尝试在两个 valarrays 之间做出区别,我希望编译器会提示 operator- 的模糊定义, 自 std::valarray已经实现了二元运算符。但这不会发生:它使用 <valarray> 进行编译。执行。为什么这不会引发错误?

最佳答案

这是模棱两可的,因为编译器只查看函数签名来测试模棱两可,而不是函数体。在您的示例中,这是函数签名:

template<typename pointType>
pointType operator-(pointType a, const pointType & b)

这里,模板参数 pointType可以推导出为 std::chrono::time_point .但是, chrono 中已经声明了一个二元减号运算符。 std::chrono::time_point 的标题( https://en.cppreference.com/w/cpp/chrono/time_point/operator_arith2)。这就是导致歧义错误的原因。

要解决这个问题,首先要考虑是否需要这样一个通用的二元减号运算符。您当前遇到的问题不是 std::chrono::time_point 独有的。 , 但也将出现在包含具有成员或非成员二进制减号运算符的类的任何其他 header 中,其中两个参数属于相同类型(或可以隐式转换为相同类型)。也许有问题类型的一组简单的函数重载:
template<typename T>
std::vector<T> operator-(const std::vector<T>& a, const std::vector<T>& b);

template<typename T, size_t N>
std::array<T,N> operator-(const std::array<T,N>& a, const std::array<T,N>& b);

这将是最安全的选择。您也不能完全使用运算符重载,而是坚持使用常规功能:
template<typename T>
T pointwise_subtract(const T& a, const T& b);

如果你有一个 c++20 编译器,你可以使用概念。如果您坚持使用非成员运算符模板,则可能必须使用基于 SFINAE 的模板元编程,这是一种更高级且可读性更低的技术:
//enable this template if the type T has a member method "size" and 
// subscript operator accepting variables of type "size_t"
template<typename T, typename=std::void_t<
decltype(std::declval<T>().size()),
decltype(std::declval<T>()[std::declval<size_t>()])
>
T operator-(const T& a, const T& b);

这将消除您的歧义错误。

关于c++ - 编译器抛出 "ambiguous overload for operator",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61533940/

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