如果在类temlpate中使用,fstream是否在编译期间通过读写访问硬盘?

问题描述 投票:0回答:1

请考虑以下此类模板的代码片段...

template<class T>
class FileTemplate {
private:
    std::vector<T>   vals_;
    std::string  filenameAndPath_;

public:
    inline FileTemplate( const std::string& filenameAndPath, const T& multiplier ) :
    filenameAndPath_( filenameAndPath ) {

        std::fstream file;
        if ( !filenameAndPath_.empty() ) {
            file.open( filenameAndPath_ );
            T val = 0;

            while ( file >> val ) {
                vals_.push_back( val );
            }

            file.close();

            for ( unsigned i = 0; i < vals_.size(); i++ ) {
                vals_[i] *= multiplier;
            }

            file.open( filenameAndPath_ );

            for ( unsigned i = 0; i < vals_.size(); i++ ) {
                file << vals_[i] << " ";
            }

            file.close();

        }
    }

    inline std::vector<T> getValues() const {
        return vals_;
    }

};

当在main中使用时,下部用以下预先填充的文本文件注释掉:

values.txt

1 2 3 4 5 6 7 8 9

int main() {

    std::string filenameAndPath( "_build/values.txt" );
    std::fstream file;

    FileTemplate<unsigned> ft( filenameAndPath, 5 );

    std::vector<unsigned> results = ft.getValues();

    for ( auto r : results ) {
        std::cout << r << " ";
    }
    std::cout << std::endl;

    /*
    FileTemplate<float> ft2( filenameAndPath, 2.5f );
    std::vector<float> results2 = ft2.getValues();

    for ( auto r : results2 ) {
        std::cout << r << " ";
    }
    std::cout << std::endl;
    */

    std::cout << "\nPress any key and enter to quit." << std::endl;
    char q;
    std::cin >> q;
    return 0;
}

我通过调试器运行此代码,确保将屏幕和文件的输出都更改为

values.txt - 覆盖 -

5 10 15 20 25 30 35 40 45 

然后让我说我不改变任何代码只是停止调试或运行应用程序,让我们说我再次运行2次,输出分别是:

values.txt - 迭代2和3

25 50 75 100 125 150 175 200 225 250

125 250 375 500 625 750 875 1000 1125 1250

好的,到目前为止;现在让我们将文本文件中的值重置为默认值,并允许取消注释具有乘数值2.5f的浮点数的此类模板的第二个实例,然后运行3次。

values.txt - 重置为默认值

 1 2 3 4 5 6 7 8 9

-iterations 1,2&3,无符号和浮点数乘数分别为<5,2.5>。 5表示无符号,2.5表示浮点数


- Iteration 1

费用:

 5 10 15 20 25 30 35 40 45
 12.5 25 37.5 50 62.5 75 87.5 100 112.5

values.txt:

 12.5 25 37.5 50 62.5 75 87.5 100 112.5


- Iteration 2

费用:

 60
 150 12.5 62.5 93.75 125 156.25 187.5 218.75 250 281.25

values.txt:

 150 12.5 62.5 93.75 125 156.25 187.5 218.75 250 281.25


- Iteration 3

费用:

 750 60
 1875 150 12.5 156.25 234.375 312.5 390.625 468.75 546.875 625 703.125

values.txt:

 1875 150 12.5 156.25 234.375 312.5 390.625 468.75 546.875 625 703.125

我想到了几个问题:关于这个程序的相同行为,它有两个问题。

第一个和主要的问题是:文件读取和写入调用是否在编译时完成,考虑到这是一个类模板,构造函数是内联的?

运行调试器几次后;为什么输出会增加文件中的值的数量?我从9开始,但经过一次迭代后,有10个,然后是11个。


这部分只是为了好玩,如果你想回答:

第三个也是最后一个问题是基于意见,但仅仅是出于教育目的,我希望看到社区对此有何看法:这类编程的优缺点是什么?有什么潜力和极限?他们的实际应用和生产是否有益于此?

c++ templates fstream hard-drive compile-time
1个回答
1
投票

就其他问题而言。主要问题是当你执行第二个file.open语句时,你没有截断文件,你需要:

file.open( filenameAndPath_, std::fstream::trunc|std::fstream::out );

发生的事情是,当你从包含浮点的文件中读取unsigned int时,它只读取第一个数字(例如12.5)直到小数位然后停止(例如只读取12个),因为没有其他在看起来像unsigned int的线上的文字。这意味着它只读取数字12,然后将其乘以5得到60,并将其写入文件。

不幸的是,因为在写入60时没有截断文件,所以它会在原始文本末尾留下原始文本,在下一个读取循环中将其解释为附加数字。因此,12.5在文件中显示为60 5

stream buffers从流中提取尽可能多的字符,并将它们插入由sb指向的流缓冲区对象(如果有)控制的输出序列中,直到输入序列耗尽或函数无法插入到指向的对象中SB。

(Qazxswpoi)

© www.soinside.com 2019 - 2024. All rights reserved.