我想定义一个带有unsigned int
as参数的函数,并向参数返回一个int
全等模UINT_MAX + 1.
第一次尝试可能如下所示:
int unsigned_to_signed(unsigned n)
{
return static_cast<int>(n);
}
Run Code Online (Sandbox Code Playgroud)
但正如任何语言律师所知,从无符号转换为大于INT_MAX的已签名值是实现定义的.
我想实现这一点,以便(a)它只依赖于规范规定的行为; (b)它在任何现代机器上编译成无操作并优化编译器.
对于奇怪的机器......如果没有签名的int congruent将UINT_MAX + 1模数为unsigned int,那么假设我想抛出一个异常.如果有多个(我不确定这是否可能),那么就说我想要最大的一个.
好的,第二次尝试:
int unsigned_to_signed(unsigned n)
{
int int_n = static_cast<int>(n);
if (n == static_cast<unsigned>(int_n))
return int_n;
// else do something long and complicated
}
Run Code Online (Sandbox Code Playgroud)
当我不是一个典型的二元补充系统时,我并不太关心效率,因为我认为不太可能.如果我的代码成为2050年无所不在的符号量级系统的瓶颈,那么,我敢打赌,有人可以解决这个问题并对其进行优化.
现在,第二次尝试非常接近我想要的.尽管转换int
为某些输入的实现定义,但是unsigned
标准保证转换为保留模UINT_MAX + 1的值.所以条件确实检查我想要什么,它将在我可能遇到的任何系统上编译成什么.
但是......我仍然在int
没有首先检查它是否会调用实现定义的行为.在2050年的一些假设系统中,它可以做谁知道什么.所以我想说我想避免这种情况.
问题:我的"第三次尝试"应该是什么样的?
回顾一下,我想:
[更新]
让我举一个例子来说明为什么这不是一个微不足道的问题.
考虑具有以下属性的假设C++实现:
sizeof(int)
等于4sizeof(unsigned)
等于4INT_MAX
等于32767INT_MIN
等于-2 …struct X
{
X() { std::cout << "X()\n"; }
X(int) { std::cout << "X(int)\n"; }
};
const int answer = 42;
int main()
{
X(answer);
}
Run Code Online (Sandbox Code Playgroud)
我本来希望这打印
X(int)
,因为X(answer);
可以解释为铸件从int
到X
,或X(answer);
可以解释为变量的声明.但是,它打印X()
,我不知道为什么X(answer);
会调用默认构造函数.
奖励积分:我需要更改什么才能获得临时而非变量声明?
C++规范的哪一部分限制参数依赖查找在相关命名空间集合中查找函数模板?换句话说,为什么main
下面的最后一次调用无法编译?
namespace ns {
struct foo {};
template<int i> void frob(foo const&) {}
void non_template(foo const&) {}
}
int main() {
ns::foo f;
non_template(f); // This is fine.
frob<0>(f); // This is not.
}
Run Code Online (Sandbox Code Playgroud) 难道C++ 11标准库提供任何实用程序从一个转换std::shared_ptr
到std::unique_ptr
,或反之亦然?这是安全的操作吗?
这似乎是一个愚蠢的问题,但是return xxx;
在一个明确定义的函数中"执行" 的确切时刻?
请参阅以下示例以了解我的意思(现在直播):
#include <iostream>
#include <string>
#include <utility>
//changes the value of the underlying buffer
//when destructed
class Writer{
public:
std::string &s;
Writer(std::string &s_):s(s_){}
~Writer(){
s+="B";
}
};
std::string make_string_ok(){
std::string res("A");
Writer w(res);
return res;
}
int main() {
std::cout<<make_string_ok()<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我天真地期待发生的事情make_string_ok
被称为:
res
被调用(价值res
就是"A"
)w
调用构造函数return res
被执行.应该返回res的当前值(通过复制当前值res
),即"A"
.w
被称为析构函数,值res
变为"AB"
.res
函数被称为.所以我希望"A"
结果,但"AB" …
我编写了一个简单的多线程程序,如下所示:
static bool finished = false;
int func()
{
size_t i = 0;
while (!finished)
++i;
return i;
}
int main()
{
auto result=std::async(std::launch::async, func);
std::this_thread::sleep_for(std::chrono::seconds(1));
finished=true;
std::cout<<"result ="<<result.get();
std::cout<<"\nmain thread id="<<std::this_thread::get_id()<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
它通常表现在调试模式下在Visual Studio中或-O0
在GC c和后打印出的结果1
秒钟。但是它卡住了,在“ 释放”模式或中不打印任何内容-O1 -O2 -O3
。
任何人都可以用简单的英语解释什么是std :: memory_order,以及如何将它们与std :: atomic <>一起使用?
我在这里找到了参考文献和一些例子,但根本不了解. http://en.cppreference.com/w/cpp/atomic/memory_order
谢谢.
由于我们在C++中移动了语义,所以现在通常这样做
void set_a(A a) { _a = std::move(a); }
Run Code Online (Sandbox Code Playgroud)
原因是,如果a
是左值,则副本将被删除,并且只有一个移动.
但如果a
是左值,会发生什么?似乎将有一个复制结构,然后是一个移动赋值(假设A有一个适当的移动赋值运算符).如果对象具有太多成员变量,则移动分配可能成本很高.
另一方面,如果我们这样做
void set_a(const A& a) { _a = a; }
Run Code Online (Sandbox Code Playgroud)
只有一个副本分配.如果我们传递左值,我们可以说这种方式优于传值的习语吗?
我在最近的一次采访中被问到有关C++结构字段对齐的问题,并且理论上C和C++在结构打包中遵循相同的策略.
Hovewer,这是错误的假设.采访者说,一般来说,C和C++以不同的方式包装结构,我们永远不应该期待相反的结果.恕我直言,这是一个奇怪的声明.pack "C"
在C++中没有用于双语C/C++头文件的结构限定符.
因此在实践中,它可能意味着您无法在C++中创建结构并将其传递给C库,因为通常它的字段将以不同的方式对齐并具有不同的偏移量.但实际上,大多数程序员都非常依赖这种互操作性,直到他们将一个指向C POD结构的指针转换为对这个结构的C++包装器的引用,并使用了一些辅助方法.你能澄清一下这个问题吗?
我正在尝试定义基类,它只包含typedef.
template<typename T>
class A
{
public:
typedef std::vector<T> Vec_t;
};
template<typename T>
class B : public A<T>
{
private:
Vec_t v; // fails - Vec_t is not recognized
};
Run Code Online (Sandbox Code Playgroud)
BI中为什么会收到Vec_t无法识别的错误,我需要明确写出来?
typename A<T>::Vec_t v;
Run Code Online (Sandbox Code Playgroud) c++ ×10
c++11 ×2
name-lookup ×2
atomic ×1
c ×1
c++17 ×1
casting ×1
copy-elision ×1
data-race ×1
inheritance ×1
integer ×1
memory-model ×1
pointers ×1
shared-ptr ×1
stdatomic ×1
struct ×1
syntax ×1
templates ×1
typedef ×1
unique-ptr ×1