小编Edw*_*ard的帖子

在`main`可选的结尾处使`return 0`的理由是什么?

从C99标准开始,编译器需要生成等效的a return 0或者return EXIT_SUCCESS如果在结尾处没有提供返回main.在同一时间,对C++语言标准也进行了相应且相同的更改.我对两者的原因感兴趣,并且我猜测它们不太可能是完全独立且无关的变化.

我的问题是:

这种变化的记录理由是什么?

一个理想的答案将引用C和C++的权威来源,这就是我用两种语言标记问题的原因.

请注意,与问题不同,在ISO C++中,从main返回0的原因是什么?,我不是在询问是否写return 0我的程序的建议 - 我问的是为什么语言标准本身已经改变了.


为了帮助理解问题的目的,这里有更多的背景:

  1. 了解更改原因有助于决定如何使用它.
  2. 理由通常包含在标准本身中.例如,C90标准包括许多解释性脚注,例如脚注36,其开头是"此列表的意图......"

在我问到这个问题之前,我已经研究了自己寻找答案的标准,但没有找到答案.我被要求帮助为一组程序员编写两种语言的编码标准,我想确保我理解为什么这个功能存在,以便我可以准确地向其他人解释它的用途.

c c++ language-lawyer

32
推荐指数
2
解决办法
1469
查看次数

如何使用std :: imbue设置std :: wcout的语言环境?

我试图使用std::localeC++ 11中的机制来计算不同语言的单词.具体来说,我有std::wstringstream一本着名的俄罗斯小说(英文"罪与罚")的标题.我想要做的是使用适当的语言环境(ru_RU.utf8在我的Linux机器上)来读取字符串流,计算单词并打印结果.我还应该注意,我的系统设置为使用en_US.utf8语言环境.

期望的结果是:

0: "????????????"
1: "?"
2: "?????????"

I counted 3 words.
and the last word was "?????????"
Run Code Online (Sandbox Code Playgroud)

这一切都在我设置全局区域设置时有效,但在我尝试imbue使用wcout流时则不行.当我尝试这个时,我得到了这个结果:

0: "????????????"
1: "?"
2: "?????????"

I counted 3 words.
and the last word was "?????????"
Run Code Online (Sandbox Code Playgroud)

此外,当我尝试使用评论中建议的解决方案时(可以通过更改#define USE_CODECVT 0来激活#define USE_CODECVT 1)我得到了另一个问题中提到的错误.

那些对代码进行试验,或者使用编译器设置或两者都感兴趣的人可能希望使用这个实时代码.

我的问题

  1. 为什么这不起作用?是因为wcout已经开放了吗?
  2. 有没有办法使用imbue而不是设置全局区域设置来做我想要的?

如果它有所作为,我正在使用g ++ 4.8.3.完整代码如下所示.

getwords.cpp

#include <iostream>
#include <fstream>
#include <sstream>
#include …
Run Code Online (Sandbox Code Playgroud)

c++ locale c++11

19
推荐指数
2
解决办法
7786
查看次数

如何编写可以使用const迭代器的C++ 11模板

在回答关于CodeReview的这个问题时,我在思考如何编写模板函数来指示const包含对象的内容.

具体而言,请考虑这个模板化函数

#include <iostream>
#include <numeric>
#include <vector>

template <class It>
typename std::iterator_traits<It>::value_type average(It begin, It end) {
    typedef typename std::iterator_traits<It>::value_type real;
    real sum = real();
    unsigned count = 0;
    for ( ; begin != end; ++begin, ++count)
        sum += *begin;
    return sum/count;
}

int main()
{
    std::vector<double> v(1000);
    std::iota(v.begin(), v.end(), 42);
    double avg = average(v.cbegin(), v.cend());
    std::cout << "avg = " << avg << '\n';
}
Run Code Online (Sandbox Code Playgroud)

它需要一个迭代器并根据包含的数字计算平均值,但保证不通过传递的迭代器修改向量.如何将此传达给模板的用户?

请注意,声明如下:

template <class It>
typename std::iterator_traits<It>::value_type average(const It …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 c++-concepts

17
推荐指数
1
解决办法
1515
查看次数

用g ++和clang ++打破std :: get_time吗?

我今天正在使用一些时间函数,并注意到使用%r(或%p)的标准转换似乎不适用于通过std::get_time()g ++或clang ++ 进行输入.请参阅 g ++和clang ++的实时代码版本.这确实似乎窗户用VC下按预期运行++(见密切相关的问题).另请注意,无论是否imbue包含该行,效果都相同.我的Linux机器上的语言环境设置为"en_US.UTF-8"重要.

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <ctime>

int main(){
    std::tm t{};
    std::stringstream ss{"1:23:45 PM"};
    ss.imbue(std::locale(std::cin.getloc(), 
             new std::time_get_byname<char>("en_US")));
    ss >> std::get_time(&t, "%r");
    if (ss.fail()) {
        std::cout << "Conversion failed\n" << std::put_time(&t, "%r") << '\n';
    } else {
        std::cout << std::put_time(&t, "%r") << '\n';
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ time c++11 c++14

13
推荐指数
1
解决办法
718
查看次数

std :: bitset的二进制序列化

std::bitset有一种to_string()序列化为s和s 的char基于字符串的方法.显然,这对于bitset中的每个位使用单个8位,使得序列化表示比所需的长8倍. 我想将bitset存储在二进制表示中以节省空间.仅当我的bitset中少于32位时,该方法才有意义.我有几百个. 我不确定我是否想在对象(地址)本身上使用/ ,因为它假设对象是POD.10char
to_ulong()
memcpy()std::copy()

API似乎没有提供内部数组表示的句柄,我可以从中获取地址.

我还想选择从二进制表示中反序列化bitset.

我怎样才能做到这一点?

c++ binary stl bitset

12
推荐指数
1
解决办法
6276
查看次数

从TCL脚本中设置环境变量

我正在创建一个Tcl脚本,这将允许我自动安装软件.但我遇到的问题是软件需要预先设置一些环境变量,我想知道是否可以在tcl脚本中设置环境变量.

我打算尝试,exec /bin/sh -c "source /path/to/.bash_profile但是会创建一个shell脚本并将变量输入到那里,然后tcl脚本就不会选择它.

谁能提出任何其他想法?

tcl environment-variables

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

constexpr将十六进制字符转换为std :: string

我有很多像这样的字符串:

"343536"_hex
Run Code Online (Sandbox Code Playgroud)

我想将其转换为相应的字节字符串.我正在使用C++ 11并定义了一个用户定义的字符串文字,将它们转换为十六进制字符串.但是,我目前的转换不能被评估为constexpr我正在寻求的.特别是我想使用这样的东西,但作为一个constexpr:

std::string operator "" _hex(const char *s, std::size_t slen )
{
    std::string str;
    str.reserve(slen);
    char ch[3];
    unsigned long num;
    ch[2] = '\0';

    for ( ; slen; slen -= 2, s += 2) {
        ch[0] = s[0];
        ch[1] = s[1];
        num = strtoul(ch, NULL, 16);
        str.push_back(num);
    }
    return str;
}
Run Code Online (Sandbox Code Playgroud)

测试司机

int main()
{
    std::string src{"653467740035"_hex};
    for (const auto &ch : src)
        std::cout << std::hex << std::setw(2) << std::setfill('0') 
                  << (unsigned)ch << '\n';
} …
Run Code Online (Sandbox Code Playgroud)

c++ string type-conversion c++11

6
推荐指数
1
解决办法
600
查看次数

如何避免使用`asio :: ip :: tcp :: iostream`进行数据竞争?

我的问题

当使用两个线程发送和接收时,如何避免数据竞争asio::ip::tcp::iostream

设计

我正在编写一个使用asio::ip::tcp::iostream输入和输出的程序.程序通过端口5555接受来自(远程)用户的命令,并通过相同的TCP连接将消息发送给用户.因为这些事件(从用户接收的命令或发送给用户的消息)是异步发生的,所以我有单独的发送和接收线程.

在这个玩具版本中,命令是"一个","两个"和"退出".当然"退出"退出该计划.其他命令不执行任何操作,任何无法识别的命令都会导致服务器关闭TCP连接.

传输的消息是简单的序列编号消息,每秒发送一次.

在这个玩具版本和我正在尝试编写的实际代码中,发送和接收进程都使用阻塞IO,因此似乎没有一种使用std::mutex其他同步机制的好方法.(在我的尝试中,一个进程会获取互斥锁然后阻塞,这对此无效.)

构建和测试

为了构建和测试它,我在64位Linux机器上使用gcc版本7.2.1和valgrind 3.13.建立:

g++ -DASIO_STANDALONE -Wall -Wextra -pedantic -std=c++14 concurrent.cpp -o concurrent -lpthread
Run Code Online (Sandbox Code Playgroud)

要测试,我使用以下命令运行服务器:

valgrind --tool=helgrind --log-file=helgrind.txt ./concurrent 
Run Code Online (Sandbox Code Playgroud)

然后我telnet 127.0.0.1 5555在另一个窗口中使用来创建与服务器的连接.什么helgrind正确地指出的是,有一个数据竞争,因为两者runTxrunRx试图以异步方式访问相同的数据流:

== 16188 ==线程#1在0x1FFEFFF1CC读取大小1期间可能发生数据竞争

== 16188 ==持有的锁:无

...更多的线路被省略了

concurrent.cpp

#include <asio.hpp>
#include <iostream>
#include <fstream>
#include <thread>
#include <array>
#include <chrono>

class Console {
public:
    Console() :
        want_quit{false},
        want_reset{false}
    {}
    bool getQuitValue() const { return want_quit; }
    int run(std::istream …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading tcp boost-asio c++14

6
推荐指数
1
解决办法
298
查看次数

为什么std :: sort将元素与自身进行比较

正如主题所说,为什么以下代码将一些元素与自己进行比较?

#include <iostream>
#include <vector>
#include <algorithm>

class a {
public:
    a(int value): value(value) {}
    ~a() {}

    bool operator<(const a& rhs) const {
        if(this->value == rhs.value)
            std::cout << this << " " << this->value << "\t" 
                << &rhs << " " << rhs.value << std::endl;
        if(this->value < rhs.value)
            return true;
        return false;
    }

    int value;
};

int main(int argc, char* argv[]) {
    std::vector<a> vec;

    for(int i = 0; i < 17; i++)
        vec.push_back(a(i));

    std::sort(vec.begin(), vec.end());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在Windows,Linux和OpenBSD上尝试了上面的代码,它似乎在Windows上没有将元素与自身进行比较,但是在Linux和OpenBSD上都有.我的猜测是,这是因为使用了不同的库.

在Linux上我得到类似于这样的输出: …

c++ sorting comparison

5
推荐指数
1
解决办法
433
查看次数

`std :: filesystem :: path`没有标准哈希值吗?

我有一个简单的程序,旨在存储一组C++ 17 std::filesystem::path对象.既然有std::filesystem::hash_value标准的一部分,为什么这个代码不能编译而不必我自己提供std::hash

当我使用gcc 8.1.1编译和链接时,g++ -std=c++17 -NO_HASH=1 hashtest.cpp -o hashtest -lstdc++fs我的哈希函数被包含在内并且一切运行完美.但是,如果我将其更改为-NO_HASH=0,我会得到一个很长的错误消息列表,其中一个关键是:

usr/include/c++/8/bits/hashtable.h:195:21: error: static assertion failed: hash function must be invocable with an argument of key type
       static_assert(__is_invocable<const _H1&, const _Key&>{},
Run Code Online (Sandbox Code Playgroud)

如果您想玩,这是一个现场Coliru版本.

真的没有定义std::hash<std::filesystem::path>吗? 我错过了什么?

对于那些对我为什么想要这样的东西感兴趣的人,就是这样:https://codereview.stackexchange.com/questions/124307/from-new-q-to-compiler-in-30-seconds

hashtest.cpp

#include <optional>
#include <unordered_set>
#include <filesystem>
#include <string>
#include <iostream>

namespace fs = std::filesystem;

#if NO_HASH
namespace std {
    template <>
    struct hash<fs::path> {
        std::size_t operator()(const …
Run Code Online (Sandbox Code Playgroud)

c++ hash c++17

4
推荐指数
1
解决办法
640
查看次数