gpt4 book ai didi

c++ - 替换失败

转载 作者:行者123 更新时间:2023-11-28 07:57:53 26 4
gpt4 key购买 nike

我目前正在尝试编写一些灵活的编译时数学库,但遇到了一个我无法摆脱的替换失败。这是问题所在:

首先,我正在编写一个理性类,我将放置唯一需要的部分。

template<typename T>
class rational
{
static_assert(std::is_integral<T>::value, "Can only contain integral values.");

public:

constexpr rational(T numerator, T denominator);

private:

T _numerator;
T _denominator;
};

为了让库变得灵活,我试图大量使用 SFINAE,以便将运算符函数调用限制为仅有理数、有理数和有理数,但无论积分数积分的基础类型是。以下是 operator+ 的函数声明,例如:

template<typename T, typename U>
constexpr
rational<typename std::common_type<T, U>::type>
operator+(const rational<T>& lhs, const rational<U>& rhs);

template<typename T, typename U>
constexpr
typename std::enable_if<std::is_integral<U>::value, rational<typename std::common_type<T, U>::type>>::type
operator+(const rational<T>& lhs, const U& rhs);

template<typename T, typename U>
constexpr
typename std::enable_if<std::is_integral<T>::value, rational<typename std::common_type<T, U>::type>>::type
operator+(const T& lhs, const rational<U> rhs);

这是一段错误的代码。它不会因为 static_assert 而崩溃,但可能是因为替换失败:

constexpr auto r1 = rational<int>(1, 2);
constexpr auto r2 = rational<int>(2, 4);
static_assert(r1 + r2 == rational<int>(1, 1), "");

错误如下(我只保留了没有周围blabla的错误):

... required by substitution of 'template<class T, class U> constexpr typename std::enable_if<std::is_integral<T>::value, smath::rational<typename std::common_type<_Tp, _Up>::type> >::type smath::operator+(const T&, smath::rational<U>) [with T = smath::rational<int>; U = int]'
... required from here
... error: operands to ?: have different types 'smath::rational<int>' and 'int'
... required by substitution of 'template<class T, class U> constexpr typename std::enable_if<std::is_integral<U>::value, smath::rational<typename std::common_type<_Tp, _Up>::type> >::type smath::operator+(const smath::rational<T>&, const U&) [with T = int; U = smath::rational<int>]'
... required from here
... error: operands to ?: have different types 'int' and 'smath::rational<int>'

我的猜测是 g++ 会选择第一个适用于两个有理数的模板函数,并且可以接受。但是,它似乎仍在尝试应用最后两个功能,但在尝试这样做时失败了。我无法理解。欢迎提供一些帮助:)

编辑: rational 构造函数explicit 似乎解决了这个问题,这很好。但是,我仍然很想知道为什么替换如此失败。

最佳答案

问题是传递给 std::enable_if<whatever, T> 的类型.即使替换会失败,论点也需要合理,但事实并非如此。所以,使用 typename std::common_type<T, U>::type如果可能评估的类型没有此类类型,则不起作用。你还需要别的东西。有效的是创建替换失败,禁用模板参数列表中的混合整数/有理数重载:

template<typename T, typename U, typename = typename std::enable_if<std::is_integral<U>::value, void>::type>
constexpr
rational<typename std::common_type<T, U>::type>
operator+(const rational<T>& lhs, const U& rhs);

template<typename T, typename U, typename = typename std::enable_if<std::is_integral<T>::value, void>::type>
constexpr
rational<typename std::common_type<T, U>::type>
operator+(const T& lhs, const rational<U> rhs);

现在我不完全确定这是否是 gcc 问题的解决方法,或者是否有必要这样做。

关于c++ - 替换失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12290501/

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