由于 的构造函数std::shared_ptr被标记为显式构造函数,因此 like 的表达式auto p = std::make_shared<int>(1); p = new int(6);是错误的。
我的问题是为什么std::make_shared<int>(1); p = nullptr;编译?
这是前面提到的代码片段:
#include <memory>
#include <iostream>
int main()
{
auto p = std::make_shared<int>(1);
//p = new int(6);
p = nullptr;
if(!p)
{
std::cout << "not accessable any more" << std::endl;
}
p.reset();
}
Run Code Online (Sandbox Code Playgroud)
考虑以下代码:
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
void func()
{
std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
}
int main()
{
std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
func();
std::cout << "stop " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
start 18737230ms
stop 18738230ms
Run Code Online (Sandbox Code Playgroud)
我们可以看到1秒过去了才func()返回。然而,没有存储 std::future std::async(...);- 即:auto f = std::async(...)
这似乎有效 - 但我想知道它的工作机制是什么。如果我有一个 std::future (在我的小例子中是 auto f ),那么当它超出范围时,它会整理线程 - 即等待 1 秒,然后线程在幕后被处理。
进一步测试:
start 18737230ms
stop 18738230ms
Run Code Online (Sandbox Code Playgroud)
给出:
start 4448133ms
stop1 4449133ms - 1 sec …Run Code Online (Sandbox Code Playgroud) 为什么这个代码片段适用于 C++17 而编译器在使用 C++11 时会抱怨(即https://godbolt.org/z/71G91P)?此代码片段是否存在任何潜在问题?
#include<iostream>
class ctx
{
public:
int map_create(void*){std::cout << "haha" << std::endl; return 0;};
};
ctx obj;
typedef int (ctx::*ctx_mem_func)(void*);
template <ctx_mem_func func>
int regHelper(void*)
{
((&obj)->*func)(nullptr);
return 0;
}
constexpr ctx_mem_func testFunc = &ctx::map_create;
typedef int(*callBackFunc)(void*);
int reg(callBackFunc)
{
return 0;
}
int main()
{
reg(regHelper<testFunc>);
//But this expression is ok.
reg(regHelper<&ctx::map_create>);
std::cout << "this is a test" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
以下是使用 c++11(gun 10.0.2) 时的错误信息:
<source>: In function 'int main()':
<source>:30:28: error: no …Run Code Online (Sandbox Code Playgroud) 为什么std::string str(nullptr)和std::string str=nullptr是错误的?有人可以详细解释原因吗?
我对此代码片段进行了一些修改,该代码片段用于通过 ASIO API 发送\接收 ICMP 数据包。
以下是我所做的修改(完整的代码片段如下所示):
使用标准版 API 代替 提供的相应 APIBoost
std::bind而不是boost::bind开始使用共享指针
pinger(ie std::shared_ptr<pinger> sp{new pinger(io_service, argv[1])};) 的共享指针,而不是通过pinger(ie pinger p(io_service, argv[1]);) 的默认构造函数直接构造实例。pinger从std::enabled_shared_from_this<pinger>现在开始派生boost::bind不再是this指针,我习惯shared_from_this()将 a 传递给std::shared_pointer。std::bind例如:我的代码是timer_.async_wait(std::bind(&pinger::start_send, shared_from_this()));,而原始代码是 timer_.async_wait(boost::bind(&pinger::handle_timeout, this));。shared_from_this()class 的构造函数pinger, start_send(); start_receive();将 移出构造函数,并Init()使用一个名为 的新函数来调用上述两个函数。使用非抛出版本asio::raw_socket::send_to并在发生某些错误时重试发送 ICMP 数据包。
socket_.send_to(request_buffer.data(), destination_); …std::vector::push_back.I有两个声明,rvalue并且lvalue在某种程度上。据我所知,几乎所有类型(T&?T&&?T)都可以转换为const T&,所以当不同类型的对象传递给编译器时,编译器会选择哪一种std::vector::push?
我是C++新手,虽然想了很多遍,还是想不通.
根据文档(http://www.cplusplus.com/reference/vector/vector/push_back/),它说:
void push_back (const value_type& val);
void push_back (value_type&& val);
在向量的末尾添加一个新元素,在其当前最后一个元素之后。val 的内容被复制(或移动)到新元素。
为什么const std::string str="__$HOOK_FUNC_FOR_LUA_KEY@__";可以,而编译器在编译时会抱怨
const std::string str("__$HOOK_FUNC_FOR_LUA_KEY@__");?
注意:str是 C++ 类的成员变量。
演示代码:
class Demo
{
private:
const std::string str("__$HOOK_FUNC_FOR_LUA_KEY@__");
}
Run Code Online (Sandbox Code Playgroud)
以下是错误消息:
test.hpp:253:51: error: expected identifier before string constant
const std::string str("__$HOOK_FUNC_FOR_LUA_KEY@__");
^
test.hpp:253:51: error: expected ‘,’ or ‘...’ before string constant
Run Code Online (Sandbox Code Playgroud)
很明显,有 ctor for std::string(char*)。所以我真的很困惑。
根据这篇文章,它说(强调我的):
部分模板特化允许我们特化类(但不是单个函数!)
似乎不允许函数部分模板特化。那真的正确吗?
让我困惑的是为什么这些代码片段可以成功编译:
//demo1.cpp
//first code snippet(https://coliru.stacked-crooked.com/a/0868610b5be94f2c)
//Why this function template specialization compiles?
//Because this is full template specialization other than partial template specialization?Am I right?
#include <iostream>
#include <string.h>
using namespace std;
template <class T>
void f(T)
{
T d;
std::cout <<"first one" << std::endl;
}
template <>
void f<int>(int)
{
int d;
std::cout <<"second one" << std::endl;
}
int main()
{
f(5.0);
f(1);
f('a');
}
Run Code Online (Sandbox Code Playgroud)
另一个例子:
//demo2.cpp(https://coliru.stacked-crooked.com/a/7b1a94ad377ac1f6)
//Why this function template …Run Code Online (Sandbox Code Playgroud) 这是用于演示的简单代码片段。
有人告诉我,双重检查锁不正确。由于变量是非易失性的,编译器可以自由地重新排序调用或优化它们(有关详细信息,请参阅 codereview.stackexchange.com/a/266302/226000)。
但是我真的看到很多项目中确实使用了这样的代码片段。有人可以对这个问题有所了解吗?我用谷歌搜索并和我的朋友谈论它,但我仍然找不到答案。
#include <iostream>
#include <mutex>
#include <fstream>
namespace DemoLogger
{
void InitFd()
{
if (!is_log_file_ready)
{
std::lock_guard<std::mutex> guard(log_mutex);
if (!is_log_file_ready)
{
log_stream.open("sdk.log", std::ofstream::out | std::ofstream::trunc);
is_log_file_ready = true;
}
}
}
extern static bool is_log_file_ready;
extern static std::mutex log_mutex;
extern static std::ofstream log_stream;
}
//cpp
namespace DemoLogger
{
bool is_log_file_ready{false};
std::mutex log_mutex;
std::ofstream log_stream;
}
Run Code Online (Sandbox Code Playgroud)
更新:谢谢大家。InitFd()确实有更好的实现,但它确实只是一个简单的演示,我真正想知道的是,双重检查锁定是否存在任何潜在问题。
有关完整的代码片段,请参阅https://codereview.stackexchange.com/questions/266282/c-logger-by-template。
是否可以在单个进程之外的单独进程中运行每个测试用例?
当我进行测试时,我发现所有测试用例都在同一个线程中运行。这是上述代码片段:
TEST(TestSuitNameA, TestCaseName)
{
std::cout << std::this_thread::get_id() << std::endl;
}
TEST(TestSuitNameB, TestCaseName)
{
std::cout << std::this_thread::get_id() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)