某些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__宏来实现自定义的值,如果实际时间和日期不详).
实际上,如果值类型为TriviallyCopyable,则std :: copy的实现应避免多次分配,并使用大容量复制功能,例如std :: memmove
但是,该页面还指出,不采用执行策略的重载将constexpr自C ++ 20开始。该标准是否会禁止这些运行时优化(因为std::memmove不是constexpr),或者是否有一种方法可以优化constexpr运行时的功能?
以下程序在C ++ 17和更高版本中是否具有未定义的行为?
struct A {
void f(int) { /* Assume there is no access to *this here */ }
};
int main() {
auto a = new A;
a->f((a->~A(), 0));
}
Run Code Online (Sandbox Code Playgroud)
C ++ 17保证a->f在评估A调用的参数之前先对对象的成员函数进行评估。因此,来自的间接->定义是明确的。但是在输入函数调用之前,将评估参数并结束A对象的生存期(但是请参见下面的编辑内容)。通话是否仍存在未定义的行为?是否可以通过这种方式在对象的生存期之外调用它的成员函数?
[expr.ref] /6.3.2的值类别a->f为prvalue ,[basic.life] / 7仅禁止对引用了生存期对象的glvalue进行非静态成员函数调用。这是否表示通话有效?(编辑:如评论中所讨论,我可能会误会[basic.life] / 7,它可能确实适用于此。)
如果我a->~A()用delete a或new(a) A(用#include<new>)替换析构函数调用,答案是否会改变?
关于我的问题的一些详尽的编辑和说明:
如果我将成员函数调用和析构函数/删除/放置新函数分成两个语句,我认为答案很明确:
a->A(); a->f(0):UB,因为a在其生命周期之外会进行非静态成员调用。(不过请参见下面的编辑)delete a; a->f(0):同上new(a) …根据cppreference,std::type_info::operator!=被C ++ 20删除,但是std::type_info::operator==显然仍然存在。
背后的原因是什么?我可能会同意比较不平等是没有意义的,但是然后比较相等也同样是没有意义的,不是吗?
相比之下,必须编写if(!(id1 == id2))并不会使任何代码更清晰if(id1 != id2),相反,相反……
考虑这个代码:
#include <iostream>
template<typename A>
struct S{
S(const A& a){
std::cout << "L\n";
}
S(A&& a){
std::cout << "R\n";
}
};
S<int> f1(){
int a = 1;
return {a};
}
S<int> f2(){
int a = 1;
return a;
}
S<int> f3(){
int a = 1;
return {std::move(a)};
}
int main()
{
f1();
f2();
f3();
}
Run Code Online (Sandbox Code Playgroud)
输出是
左
右
右
您可能知道 C++ 在返回值中隐式移动(在 f2 中)。当我们在初始值设定项列表中手动执行时,它可以工作(f3),但它不会在 f1 中由 C++ 自动完成。
这是否有充分的理由为什么这不起作用,或者只是被认为不够重要而无法由标准指定的极端情况?
PS 我知道编译器可以(有时必须)执行 RVO,但我不明白这如何解释输出。
void foo(const auto& collection)
{
*collection.begin() = 104;
}
int main()
{
std::vector<int> ints {1, 2, 3, 4, 5};
foo(ints); // Error, as it should be
foo(ints | std::views::all); // Compiles and modifies the vector. Why?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果函数的参数是类型,为什么左值引用的常量性会被完全忽略std::view?
编辑:
如果,正如您在注释中所写,const 视图引用与此上下文中的 const 指针类似,那么如果同一函数采用从右值对象构造的视图作为参数,为什么代码无法编译?
std::vector<int> getVec()
{
return std::vector{1, 2, 3, 4, 5};
}
void foo(const auto& collection)
{
*collection.begin() = 104; // Error: assignment of read-only location
}
int main()
{
foo(getVec() | std::views::all); // Nope! …Run Code Online (Sandbox Code Playgroud) 如何使用概念if constexpr?
给出下面的例子,if constexpr如果T满足要求,则返回1 将给予integral什么?
template<typename T>
concept integral = std::is_integral_v<T>;
struct X{};
template<typename T>
constexpr auto a () {
if constexpr (/* T is integral */) {
return 1;
}
else {
return 0;
}
}
int main () {
return a<X>();
}
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
#include <cctype>
#include <functional>
#include <iostream>
int main()
{
std::invoke(std::boolalpha, std::cout); // #1
using ctype_func = int(*)(int);
char c = std::invoke(static_cast<ctype_func>(std::tolower), 'A'); // #2
std::cout << c << "\n";
}
Run Code Online (Sandbox Code Playgroud)
在此,对的两个调用std::invoke已标记为将来参考。预期的输出是:
a
Run Code Online (Sandbox Code Playgroud)
在C ++ 20中可以保证预期的输出吗?
(注意:有两个函数tolower,一个称为in <cctype>,另一个称为in <locale>。引入了显式强制转换以选择所需的重载。)
c++ c++-standard-library language-lawyer unspecified-behavior c++20
我有这段代码,输出如下:
链接到以下示例 https://godbolt.org/z/z8Pn9GsTv
template <typename T>
struct A1 {
A1() {
std::cout << "construction of a1" << std::endl;
}
~A1() {
std::cout << "destruction of a1" << std::endl;
}
~A1() requires (std::is_same_v<T,int>) {
std::cout << "it is an int" << std::endl;
}
};
int main() {
A1 <int>a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
construction of a1
destruction of a1
Run Code Online (Sandbox Code Playgroud)
但交换析构函数的位置会给出其他结果:
代码链接 https://godbolt.org/z/vxj7dPqaj
template <typename T>
struct A1 {
A1() {
std::cout << "construction of a1" << std::endl;
}
~A1() requires (std::is_same_v<T,int>) …Run Code Online (Sandbox Code Playgroud) 考虑头文件:
class T
{
private:
int const ID;
public:
explicit T(int const ID_) noexcept : ID(ID_) {}
int GetID() const noexcept { return ID; }
};
Run Code Online (Sandbox Code Playgroud)
或者,或者:
class T
{
private:
int const ID;
public:
explicit T(int const ID_) noexcept;
int GetID() const noexcept;
};
inline T::T(int const ID_) noexcept : ID(ID_) {}
inline int T::GetID() const noexcept { return ID; }
Run Code Online (Sandbox Code Playgroud)
在预模块世界中,这些标头可能会以文本形式包含在多个 TU 中,而不会违反 ODR。此外,由于涉及的成员函数相对较小,编译器可能会“内联”(在使用时避免函数调用)这些函数,甚至优化掉一些实例T。
在最近关于 C++20 完成会议的报告中,我可以阅读以下声明:
我们澄清了
inline模块接口中的含义:意图是未明确声明的函数体不是inline模块 ABI 的一部分,即使这些函数体出现在模块接口中。为了让模块作者更好地控制他们的 …
c++ ×10
c++20 ×10
c++-chrono ×1
c++-concepts ×1
c++-modules ×1
c++17 ×1
constants ×1
constexpr ×1
destructor ×1
if-constexpr ×1
optimization ×1
std-ranges ×1
time ×1