Jon*_*Mee 3 c++ member division modulo
因此,从div函数返回的成员的顺序似乎是实现定义的.
是quot1 日成员或者是rem?
让我们说我做的是这样的:
generate(begin(digits), end(digits), [i = div_t{ quot, 0 }]() mutable {
i = div(i.quot, 10);
return i.rem;
})
Run Code Online (Sandbox Code Playgroud)
当然这里的问题是我不知道我是初始化i.quot还是i.rem在我的lambda捕获中.是否i采用div(quot, 1)唯一的跨平台方式来实现这一目标?
小智 7
你没有指定成员的顺序是对的.该定义继承自C,它明确指出它是(强调我的):
7.20.6.2 div,ldiv和lldiv函数
3 [...]结构应包含(以任何顺序)成员
quot(商)和rem(其余),每个成员与参数numer和类型具有相同的类型denom.[...]
在C中,订单未指定的事实并不重要,并且具体包括以下示例div_t:
6.7.8初始化
34示例10可以将结构成员初始化为非零值,而不依赖于它们的顺序:
Run Code Online (Sandbox Code Playgroud)div_t answer = { .quot = 2, .rem = -1 };
不幸的是,C++从未采用过这种语法.
我可能会在辅助函数中进行简单的赋值:
div_t make_div_t(int quot, int rem) {
div_t result;
result.quot = quot;
result.rem = rem;
return result;
}
Run Code Online (Sandbox Code Playgroud)
对于普通int值,无论您使用初始化还是赋值都不重要,它们具有相同的效果.
您的分区1也是一个有效的选项.
我认为 VS 解决方法可能如下所示:
#include <cstdlib>
#include <type_traits>
template<class T>
struct DTMaker {
using D = decltype(div(T{}, T{}));
static constexpr D dt = D{0,1};
static constexpr auto quot = dt.quot;
};
template <class T, typename std::enable_if<DTMaker<T>::quot == 0>::type* = nullptr>
typename DTMaker<T>::D make_div(const T ", const T& rem) { return {quot, rem}; }
template <class T, typename std::enable_if<DTMaker<T>::quot == 1>::type* = nullptr>
typename DTMaker<T>::D make_div(const T ", const T &rem) { return {rem, qout}; }
int main() {
div_t d_t = make_div(1, 2);
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 c++17,您还可以尝试使用结构化绑定、constexpr 函数和 SFINAE 重载来检测结构中首先声明的字段:
#include <cstdlib>
#include <algorithm>
#include <iterator>
constexpr bool first_quot() {
auto [x, y] = std::div_t{1, 0};
(void)y;
return x;
}
template <bool B = first_quot()>
std::enable_if_t<B, std::div_t> foo() {
int quot = 1;
int rem = 0;
return {quot, rem};
}
template <bool B = first_quot()>
std::enable_if_t<!B, std::div_t> foo() {
int quot = 1;
int rem = 0;
return {rem, quot};
}
int main() {
foo();
}
Run Code Online (Sandbox Code Playgroud)
或者更简单地使用 if constexpr:
#include <cstdlib>
#include <algorithm>
#include <iterator>
constexpr bool first_quot() {
auto [x, y] = std::div_t{1, 0};
(void)y;
return x;
}
std::div_t foo() {
int quot = 1;
int rem = 0;
if constexpr(first_quot())
return {quot, rem};
else
return {rem, quot};
}
int main() {
foo();
}
Run Code Online (Sandbox Code Playgroud)