Boost 文档提到了
integer_modulus
函数。
template <class Integer1, class Integer2>
Integer2 integer_modulus(const Integer1& x, Integer2 val);
我发现它位于 boost::multiprecision
命名空间中的
boost/multi precision/integer.hpp中。但是,我不知道如何让它发挥作用。我尝试了不同的编译器,但在编译阶段遇到了相同的
no matching
和 possible candidates
错误。例子是这里。
#include <iostream>
#include <boost/multiprecision/integer.hpp>
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
using bigint_t = mp::int256_t;
int main() {
bigint_t a = -28;
bigint_t b = 10;
bigint_t c = mp::integer_modulus(a, b);
std::cout << (a % b) << std::endl;
std::cout << c << std::endl;
return 0;
}
错误:
<source>: In function 'int main()':
<source>:11:35: error: no matching function for call to 'integer_modulus(bigint_t&, bigint_t&)'
11 | bigint_t c = mp::integer_modulus(a, b);
| ~~~~~~~~~~~~~~~~~~~^~~~~~
In file included from /opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/cpp_int.hpp:20,
from /opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp:11,
from <source>:2:
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:155:1: note: candidate: 'template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Integer> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<I>::value && (boost::multiprecision::number_category<Num>::value == boost::multiprecision::number_kind_integer)), Integer>::type boost::multiprecision::integer_modulus(const number<Backend, ExpressionTemplates>&, Integer)'
155 | integer_modulus(const number<Backend, ExpressionTemplates>& x, Integer val)
| ^~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:155:1: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp: In substitution of 'template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Integer> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<I>::value && (boost::multiprecision::number_category<Num>::value == boost::multiprecision::number_kind_integer)), Integer>::type boost::multiprecision::integer_modulus(const number<Backend, ExpressionTemplates>&, Integer) [with Backend = boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>; boost::multiprecision::expression_template_option ExpressionTemplates = boost::multiprecision::et_off; Integer = boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >]':
<source>:11:35: required from here
11 | bigint_t c = mp::integer_modulus(a, b);
| ~~~~~~~~~~~~~~~~~~~^~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:155:1: error: no type named 'type' in 'struct std::enable_if<false, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >'
155 | integer_modulus(const number<Backend, ExpressionTemplates>& x, Integer val)
| ^~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:163:1: note: candidate: 'template<class tag, class A1, class A2, class A3, class A4, class Integer> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<I>::value && (boost::multiprecision::number_category<typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == boost::multiprecision::number_kind_integer)), Integer>::type boost::multiprecision::integer_modulus(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>&, Integer)'
163 | integer_modulus(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& x, Integer val)
| ^~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:163:1: note: template argument deduction/substitution failed:
<source>:11:35: note: 'bigint_t' {aka 'boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >'} is not derived from 'const boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>'
11 | bigint_t c = mp::integer_modulus(a, b);
| ~~~~~~~~~~~~~~~~~~~^~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp:46:179: note: candidate: 'template<class I1, class I2> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<T>::value && boost::multiprecision::detail::is_integral<Arithmetic>::value), I2>::type boost::multiprecision::integer_modulus(const I1&, I2)'
46 | inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I1>::value && boost::multiprecision::detail::is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val)
| ^~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp:46:179: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp: In substitution of 'template<class I1, class I2> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<T>::value && boost::multiprecision::detail::is_integral<Arithmetic>::value), I2>::type boost::multiprecision::integer_modulus(const I1&, I2) [with I1 = boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >; I2 = boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >]':
<source>:11:35: required from here
11 | bigint_t c = mp::integer_modulus(a, b);
| ~~~~~~~~~~~~~~~~~~~^~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp:46:179: error: no type named 'type' in 'struct std::enable_if<false, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >'
46 | inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I1>::value && boost::multiprecision::detail::is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val)
| ^~~~~~~~~~~~~~~
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:11:35: error: no matching function for call to 'integer_modulus(bigint_t&, bigint_t&)'
11 | bigint_t c = mp::integer_modulus(a, b);
| ~~~~~~~~~~~~~~~~~~~^~~~~~
In file included from /opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/cpp_int.hpp:20,
from /opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp:11,
from <source>:2:
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:155:1: note: candidate: 'template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Integer> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<I>::value && (boost::multiprecision::number_category<Num>::value == boost::multiprecision::number_kind_integer)), Integer>::type boost::multiprecision::integer_modulus(const number<Backend, ExpressionTemplates>&, Integer)'
155 | integer_modulus(const number<Backend, ExpressionTemplates>& x, Integer val)
| ^~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:155:1: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp: In substitution of 'template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Integer> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<I>::value && (boost::multiprecision::number_category<Num>::value == boost::multiprecision::number_kind_integer)), Integer>::type boost::multiprecision::integer_modulus(const number<Backend, ExpressionTemplates>&, Integer) [with Backend = boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>; boost::multiprecision::expression_template_option ExpressionTemplates = boost::multiprecision::et_off; Integer = boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >]':
<source>:11:35: required from here
11 | bigint_t c = mp::integer_modulus(a, b);
| ~~~~~~~~~~~~~~~~~~~^~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:155:1: error: no type named 'type' in 'struct std::enable_if<false, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >'
155 | integer_modulus(const number<Backend, ExpressionTemplates>& x, Integer val)
| ^~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:163:1: note: candidate: 'template<class tag, class A1, class A2, class A3, class A4, class Integer> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<I>::value && (boost::multiprecision::number_category<typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == boost::multiprecision::number_kind_integer)), Integer>::type boost::multiprecision::integer_modulus(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>&, Integer)'
163 | integer_modulus(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& x, Integer val)
| ^~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/detail/integer_ops.hpp:163:1: note: template argument deduction/substitution failed:
<source>:11:35: note: 'bigint_t' {aka 'boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >'} is not derived from 'const boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>'
11 | bigint_t c = mp::integer_modulus(a, b);
| ~~~~~~~~~~~~~~~~~~~^~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp:46:179: note: candidate: 'template<class I1, class I2> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<T>::value && boost::multiprecision::detail::is_integral<Arithmetic>::value), I2>::type boost::multiprecision::integer_modulus(const I1&, I2)'
46 | inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I1>::value && boost::multiprecision::detail::is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val)
| ^~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp:46:179: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp: In substitution of 'template<class I1, class I2> constexpr typename std::enable_if<(boost::multiprecision::detail::is_integral<T>::value && boost::multiprecision::detail::is_integral<Arithmetic>::value), I2>::type boost::multiprecision::integer_modulus(const I1&, I2) [with I1 = boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >; I2 = boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >]':
<source>:11:35: required from here
11 | bigint_t c = mp::integer_modulus(a, b);
| ~~~~~~~~~~~~~~~~~~~^~~~~~
/opt/compiler-explorer/libs/boost_1_85_0/boost/multiprecision/integer.hpp:46:179: error: no type named 'type' in 'struct std::enable_if<false, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >'
46 | inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I1>::value && boost::multiprecision::detail::is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val)
| ^~~~~~~~~~~~~~~
Execution build compiler returned: 1
那么,问题是:如何让它发挥作用?
您错过了文档中的一个关键点。 在您的链接中,关键点是功能
对基本(内置)整数类型进行重载
事实上,如果你查看源代码,该函数定义为
template <class I1, class I2>
typename enable_if_c<is_integral<I1>::value && is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val)
{
return static_cast<I2>(x % val);
}
正如您所看到的,它仅限于
is_integral<Type>
为 true
的类型。