如何初始化div_t对象?

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可以将结构成员初始化为非零值,而不依赖于它们的顺序:

div_t answer = { .quot = 2, .rem = -1 };
Run Code Online (Sandbox Code Playgroud)

不幸的是,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也是一个有效的选项.


W.F*_*.F. 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 &quot, 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 &quot, 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)

[现场演示]