今天我在将VS2008解决方案迁移到VS2010时遇到了这个问题.在以下任一情况中发生此问题:
如果我在其中任何一个之后做了第二个Build,问题就没出现了.使用谷歌,我真正想到的只是来自微软的一年之久的博客说他们无法重现这个问题,或者在未来的版本中修复了它.
我找到的最好的东西是:Mikazo Tech Blog:解决Visual Studio 2010中的MT.exe错误
在上面的文章中,它说该问题与Manifest生成有关,并且解决方案是在Linker - > Manifest下的设置中关闭Manifest.我不需要这个项目的清单,但我仍然不满意.
我已经解决了这个问题,我只想回答我自己的问题,因为我没有在StackOverflow上发现这个特定的错误(代码31).
(据我所知,使用的编译器是带有 c++17 的 gcc(在 Visual Studio 中很难找到))
#include <iostream>
using namespace std;
void increment( int& v )
{
++v;
}
int constexpr f()
{
int v = 0;
increment( v );
return v;
}
int main( )
{
cout << f( ) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
上面的代码给出了编译错误:
constexpr 函数 'f' 不能产生常量表达式。
据我了解,这是因为该函数increment
不是 constexpr。让我困惑的是以下代码编译得很好:
#include <iostream>
using namespace std;
void increment( int& v )
{
++v;
}
int constexpr f()
{
int v = 0;
for( int i = 0; …
Run Code Online (Sandbox Code Playgroud) 当我寻找文件中的某个位置并写入少量数据(20个字节)时,幕后会发生什么?
我的理解
据我所知,可以从磁盘写入或读取的最小数据单元是一个扇区(传统上是512字节,但该标准现在正在改变).这意味着要写20个字节,我需要读取整个扇区,在内存中修改一些并将其写回磁盘.
这是我期望在无缓冲I/O中发生的事情.我还希望缓冲的I/O做大致相同的事情,但要聪明一点.所以我会想到,如果我通过随机搜索和写入来打破窗口的局部性,缓冲和无缓冲的I/O应该具有相似的性能......也许无缓冲的出现稍微好一些.
然后,我知道缓冲I/O仅缓冲一个扇区是疯狂的,所以我也可能期望它执行得非常糟糕.
我的应用程序
我正在存储由SCADA设备驱动程序收集的值,该驱动程序接收超过十万点的远程遥测.文件中有额外的数据,每条记录是40个字节,但在更新期间只需要写入20个字节.
实施前基准
为了检查我是否不需要想出一些出色的过度设计的解决方案,我已经使用写入文件的几百万个随机记录进行测试,该文件可能包含总共200,000条记录.每个测试都使用相同的值对随机数发生器进行种子处理.首先,我擦除文件并将其填充到总长度(大约7.6兆),然后循环几百万次,将随机文件偏移量和一些数据传递给两个测试函数之一:
void WriteOldSchool( void *context, long offset, Data *data )
{
int fd = (int)context;
lseek( fd, offset, SEEK_SET );
write( fd, (void*)data, sizeof(Data) );
}
void WriteStandard( void *context, long offset, Data *data )
{
FILE *fp = (FILE*)context;
fseek( fp, offset, SEEK_SET );
fwrite( (void*)data, sizeof(Data), 1, fp );
fflush(fp);
}
Run Code Online (Sandbox Code Playgroud)
也许没有惊喜?
这个OldSchool
方法排在首位 - 很多.它的速度提高了6倍(148万,而每秒232000条记录).为了确保我没有遇到硬件缓存,我将数据库大小扩展到了2000万条记录(文件大小为763兆字节)并得到了相同的结果.
在你指出明显的呼吁之前fflush
,让我说删除它没有任何效果.我想这是因为当我寻找足够远的地方时必须提交缓存,这正是我大部分时间都在做的事情.
发生什么了?
在我看来,每当我尝试写入时,缓冲的I/O必须读取(并且可能全部写入)大块文件.因为我几乎没有利用它的缓存,这非常浪费.
另外(我不知道磁盘上硬件缓存的细节),如果缓冲I/O在我只改变一个扇区时试图编写一堆扇区,那么会降低硬件缓存的有效性.
是否有任何磁盘专家可以比我的实验结果更好地发表评论和解释?=)
我正在接受20行输入.我想用空格分隔每一行的内容并将其放入向量向量中.如何制作矢量矢量?我正在努力推回它......
我的输入文件:
Mary had a little lamb
lalala up the hill
the sun is up
Run Code Online (Sandbox Code Playgroud)
矢量应该看起来像这样.
ROW 0: {"Mary","had", "a","little","lamb"}
ROW 1: {"lalala","up","the","hill"}
Run Code Online (Sandbox Code Playgroud)
这是我的代码......
string line;
vector <vector<string> > big;
string buf;
for (int i = 0; i < 20; i++){
getline(cin, line);
stringstream ss(line);
while (ss >> buf){
(big[i]).push_back(buf);
}
}
Run Code Online (Sandbox Code Playgroud) 我想明确关于成员变量的数组大小限制,以阻止其他人意外地进行愚蠢的更改.以下天真的尝试将无法编译:
struct Foo
{
std::array< int, 1024 > some_array;
static_assert( (some_array.size() % 256) == 0, "Size must be multiple of 256" );
//^ (clang) error: invalid use of non-static data member 'some_array'
};
Run Code Online (Sandbox Code Playgroud)
即使std::array::size
是constexpr,我也不能直接使用static_assert
,因为函数和我的成员变量都不是静态的.
我想出的解决方案是使用decltype
(因为我不想键入数组),如下所示:
static_assert( (decltype(some_array)().size() % 256) == 0, "Size must be multiple of 256" );
Run Code Online (Sandbox Code Playgroud)
这看起来像是默认构造一个右值,我认为它不是一个constexpr.
为什么这样做?
有没有更简洁的方法来实现静态断言?
我有一些工作线程定期执行时间关键处理(大约1 kHz).每个周期,工人都被唤醒做家务,每个人都应该(平均)在下一个周期开始之前完成.它们在同一个对象上运行,有时可以通过主线程进行修改.
为了防止竞争,但允许在下一个循环之前修改对象,我使用了一个自旋锁和一个原子计数器来记录仍有多少线程正在工作:
class Foo {
public:
void Modify();
void DoWork( SomeContext& );
private:
std::atomic_flag locked = ATOMIC_FLAG_INIT;
std::atomic<int> workers_busy = 0;
};
void Foo::Modify()
{
while( locked.test_and_set( std::memory_order_acquire ) ) ; // spin
while( workers_busy.load() != 0 ) ; // spin
// Modifications happen here ....
locked.clear( std::memory_order_release );
}
void Foo::DoWork( SomeContext& )
{
while( locked.test_and_set( std::memory_order_acquire ) ) ; // spin
++workers_busy;
locked.clear( std::memory_order_release );
// Processing happens here ....
--workers_busy;
}
Run Code Online (Sandbox Code Playgroud)
这允许所有剩余的工作立即完成,前提是至少有一个线程已经开始,并且在另一个工作人员开始下一个周期的工作之前总是会阻塞.
在atomic_flag …
我试图在我的类中使用一个线程,然后线程需要使用a condition_variable
,条件变量将被阻塞,直到谓词被更改为true
.代码如下所示:
class myThreadClass{
bool bFlag;
thread t ;
mutex mtx;
condition_variable cv;
bool myPredicate(){
return bFlag;
}
int myThreadFunction(int arg){
while(true){
unique_lock<mutex> lck(mtx);
if(cv.wait_for(lck,std::chrono::milliseconds(3000),myPredicate)) //something wrong?
cout<<"print something...1"<<endl
else
cout<<"print something...2"<<endl
}
}
void createThread(){
t = thread(&myThreadClass::myThreadFunction,this,10);//this is ok
}
} ;
Run Code Online (Sandbox Code Playgroud)
编译时的这段代码会抛出错误说:
"wait_for"行中未解决的重载函数类型.
然后我尝试将其修改为:
if(cv.wait_for(lck,std::chrono::milliseconds(3000),&myThreadClass::myPredicate))
Run Code Online (Sandbox Code Playgroud)
但仍然存在错误.
我的扩展SwingWorker类执行可能重复发生的后台任务,该任务需要GUI发起输入变量.
我看到2个编码选项:
每次使用它时都要启动类的新实例并将变量传递给构造函数.我认为我应该确保没有很多情况.如果是这样的话?multiton或其他一些方法?
更新变量并再次调用execute?如果是这样,我如何确保我不打扰?
这些选项中的一种是可行的方式还是有更好的方法?
我担心我违反了mutable
我用于在异步执行按需请求的数据模型中缓存信息的合同。数据模型恰好是 Qt,尽管这不是一个特别重要的事实。
class MyDataModel : public QAbstractItemModel
{
public:
QVariant data( const QModelIndex & index, int role ) const override;
private:
void SignalRowDataUpdated( int row ) const;
mutable SimpleRowCache mCache;
};
Run Code Online (Sandbox Code Playgroud)
当data()
被调用时,我检查缓存以查看是否有缓存。如果没有,我会立即返回空数据(以避免阻塞 UI)并向 API 发送异步请求以填充缓存。由于data()
must 是 const,这要求它mCache
是可变的。的胆量是data()
这样的:
RowData row_data = mCache.Get( row );
if( !row_data )
{
// Store empty data in cache, to avoid repeated API requests
mCache.Set( row, RowData() );
// Invoke API with a lambda to deliver …
Run Code Online (Sandbox Code Playgroud) 我正在优化一种压缩算法,该算法使用跨 2 个字节的结构。但有时我希望它只解释 1 个字节,因为(我希望)映射到第二个字节的成员永远不会被写入或读取。
我是否能保证编译器不会访问第二个字节,只要 和zFmt
永远wFmt
不会被访问?如果不是,我可以编写一个静态断言,当这个假设错误时将停止编译吗?
struct Header {
uint8_t xFmt : 4;
uint8_t yFmt : 4;
uint8_t zFmt : 4; // must not be read/written when header is mapped to 1 byte
uint8_t wFmt : 4; // must not be read/written when header is mapped to 1 byte
};
static_assert( sizeof(Header) == 2 && alignof(Header) == 1, "alignment vital");
// --- usage ---
int main(){
// Header may be placed into memory where it …
Run Code Online (Sandbox Code Playgroud)