小编use*_*163的帖子

符合标准的C++实现如何表明它不知道当前的日期和时间?

某些C++实现(例如,电池供电的嵌入式设备)可能没有用或无法跟踪当前的日期和时间.

C标准具体地允许这样的实施方式.引用ISO/IEC 9899:1999 7.23.2.4(强调我的):

time函数返回实现对当前日历时间的最佳近似值.如果日历时间不可用,则返回值(time_t)( - 1).

C++ 11引入了chrono库和std::chrono::system_clock::now()函数,用于从系统范围的实时时钟获取挂钟时间.该函数被声明为noexcept,因此它不能抛出任何异常来指示不可用,也不允许返回任何特殊值(如-1C的情况).

但是对于C++ 11,C++ 14和C++ 17,仍然存在漏洞.标准没有指定时钟的纪元,因此符合要求的实施可以将纪元设置为启动时(或程序启动)并仍满足标准要求的时间点.

目前的C++ 20草案将填补这个漏洞并需要system_clock使用Unix时间.换句话说,不知道当前时间的C++实现是不符合的.

这是标准委员会的疏忽吗?符合标准的C++实现如何表明它不知道当前的日期和时间?

(请注意,在标准的其它部分这一问题得到解决.例如,一个实现可以设置__TIME____DATE__宏来实现自定义的值,如果实际时间和日期不详).

c++ time language-lawyer c++-chrono c++20

28
推荐指数
1
解决办法
977
查看次数

具有两个参数包的函数模板重载决策

请考虑以下代码:

#include<iostream>

template<class..., class... T>
int f(T...) { return 1; }

template<class... T>
int f(T...) { return 2; }

int main()
{
    std::cout << f(1);
}
Run Code Online (Sandbox Code Playgroud)

1在gcc 8.2上编译和打印,但由于调用f(1)不明确而无法在clang 7上编译.

如果调用被替换为f()两个编译器都无法编译声称调用是不明确的.

如果参数包class... T被以简单的参数替换class T(和T...T),二者编译器也要求歧义.

在第一个示例中,哪个编译器符合标准?我想这归结为功能模板的特定部分排序规则,还是以这种方式使用双参数包已经形成错误了?

编辑:

我的理解是双包本身并不是格式错误,因为我的阅读中的[temp.param] 17.1/15似乎明确允许这个,如果第二个包可以从函数参数中推导出来,这似乎是因为该T...函数参数包.

也可以显式指定第一个参数包的参数,但不是第二个参数包的参数,因此并不总是(在模板参数推断之后)至少一个参数包为空.我不确定这是否会使程序格式不正确,因为我不知道在这种情况下如何阅读例如[temp.res] 17.7/8.3.

gcc和clang似乎都没有双参数包本身,例如当第二个函数模板重载被删除时,两个编译器都打印1.但这可能是形成不良的情况,无需诊断.

此外,我假设使用类模板参数推导,可变参数类模板可以定义一个可变参数构造函数模板,这意味着构造函数候选类似于我的双参数包示例,据我所知,相同的重载决议和模板参数推导需要在这种情况下.这个问题是由另一个带有这样设置的问题所驱动的:Variadic类模板推导失败,使用gcc 8.2,编译clang和msvc 另请参阅讨论:使用可变参数模板构造函数的演绎指南和可变参数类模板 - 不匹配的参数包长度

现在我也找到了问题的演绎指南和可变参数模板的答案,我假设gcc是错误的并且调用应该被认为是模棱两可的,但我想让它验证这适用于这里同样的方式.我也会更加详细地欢迎推理,因为功能模板偏序规则对我来说似乎很不清楚.

c++ language-lawyer overload-resolution template-argument-deduction

9
推荐指数
1
解决办法
210
查看次数

constexpr中的std :: variant修改

考虑以下两个程序:

#include<variant>
#include<iostream>

constexpr auto f() {
    using T = std::variant<bool, int>;
    T t(false);
    t = T(true);
    return std::get<bool>(t);
}

template<auto V> 
void print() { std::cout << V << "\n"; }

int main() {
    print<f()>();
}
Run Code Online (Sandbox Code Playgroud)

#include<variant>
#include<iostream>

constexpr auto f() {
    using T = std::variant<bool, int>;
    T t(false);
    t = T(42);
    return std::get<int>(t);
}

template<auto V> 
void print() { std::cout << V << "\n"; }

int main() {
    print<f()>();
}
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会汇编这两项并输出预期结果.在两种情况下,Clang都不会使用以下错误消息编译它们中的任何一个:

<source>:4:16: error: constexpr function never produces a …
Run Code Online (Sandbox Code Playgroud)

c++ variant constexpr c++17

7
推荐指数
1
解决办法
519
查看次数

libc ++的std :: is_literal_type如何工作?

对于std::is_literal_type和,这是相同的情况std::is_standard_layout.

std::is_literal_type在libc ++中的实现是

template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_literal_type
#ifdef _LIBCPP_IS_LITERAL
    : public integral_constant<bool, _LIBCPP_IS_LITERAL(_Tp)>
#else
    : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value ||
                              is_reference<typename remove_all_extents<_Tp>::type>::value>
#endif
    {};
Run Code Online (Sandbox Code Playgroud)

没有_LIBCPP_IS_LITERAL,所以代码将是

template <typename T> struct is_literal_type : integral_constant<bool,
    is_scalar<typename remove_all_extents<T>::type>::value or
    is_reference<typename remove_all_extents<T>::type>::value> {};
Run Code Online (Sandbox Code Playgroud)

我写了一个演示:

#include <iostream>

using namespace std;
struct s {
    int a;
    char b;
    long c;
};
int main(int argc, char *argv[]) {
    cout << boolalpha;
    cout << is_scalar_v<typename remove_all_extents<s>::type> << endl;
    cout << is_reference_v<typename …
Run Code Online (Sandbox Code Playgroud)

c++ std c++-standard-library libc++ c++17

2
推荐指数
1
解决办法
104
查看次数