在Bjarne Stroustrup的主页(C++ 11 FAQ)中:
struct X { int foo(int); };
std::function<int(X*, int)> f;
f = &X::foo; //pointer to member
X x;
int v = f(&x, 5); //call X::foo() for x with 5
Run Code Online (Sandbox Code Playgroud)
它是如何工作的?std :: function如何调用foo成员函数?
模板参数int(X*, int)
,是&X::foo
从转换成员函数指针到一个非成员函数指针?!
(int(*)(X*, int))&X::foo //casting (int(X::*)(int) to (int(*)(X*, int))
Run Code Online (Sandbox Code Playgroud)
澄清:我知道我们不需要使用任何指针来使用std :: function,但我不知道std :: function的内部如何处理成员函数指针和非成员函数之间的这种不兼容性指针.我不知道标准如何允许我们实现像std :: function这样的东西!
关于C++标准:
std::function
GNU Compiler Collection 是否使用union
数据类型在不同的函数指针类型之间进行转换(例如,将非静态成员函数指针转换为非成员函数指针)?union
数据类型但不进行强制转换(类型擦除).undefined behavior
在不同的函数指针类型之间进行转换(在C++或C++ 11标准中)吗?我认同.std::function
不使用任何具有undefined behavior
?的代码的情况下实现?以下是我的问题:
我们有时必须编写undefined behavior
符合C++标准的代码(但它们defined behavior
适用于特定的C++编译器,如GCC或MSVC)?
这是否意味着我们不能/不应该阻止undefined behavior
我们的C++代码?
plugin1.cpp:
#include <iostream>
static class TestStatic {
public:
TestStatic() {
std::cout << "TestStatic create" << std::endl;
}
~TestStatic() {
std::cout << "TestStatic destroy" << std::endl;
}
} test_static;
Run Code Online (Sandbox Code Playgroud)
host.cpp
#include <dlfcn.h>
#include <iostream>
int main(int argc,char *argv[]) {
void* handle = dlopen("./plugin1.so",RTLD_NOW | RTLD_LOCAL );
dlclose(handle);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
构建和运行:
>g++ -c plugin1.cpp -o plugin1.o -fPIC
>g++ -shared plugin.o -o plugin1.so
>g++ host.cpp -o host -ldl
>./host
>TestStatic create
>Segmentation fault
Run Code Online (Sandbox Code Playgroud)
为什么TestStatic :: ~TestStatic在'exit()'处调用但不在'dlclose()'处调用?
例如,这是我的成员函数(do_it
):
class oops
{
public:
void do_it(GtkWidget *widget, GdkEvent *event, gpointer data)
{
g_print ("Hi there :)\n");
}
};
Run Code Online (Sandbox Code Playgroud)
...我用std::bind
它来使它看起来像一个非成员函数:
oops o;
std::function<void(GtkWidget*, GdkEvent*, gpointer)> f = std::bind(&oops::do_it, o);
Run Code Online (Sandbox Code Playgroud)
但它不起作用,以下是编译器错误消息:
program.cc: In function ‘int main(int, char**)’:
program.cc:69:85: error: conversion from ‘std::_Bind_helper<false, void (oops::*)(_GtkWidget*, _GdkEvent*, void*), oops&>::type {aka std::_Bind<std::_Mem_fn<void (oops::*)(_GtkWidget*, _GdkEvent*, void*)>(oops)>}’ to non-scalar type ‘std::function<void(_GtkWidget*, _GdkEvent*, void*)>’ requested
std::function<void(GtkWidget*, GdkEvent*, gpointer)> f = std::bind(&oops::do_it, o);
^
Run Code Online (Sandbox Code Playgroud)
我必须使用std::placeholders
以下方法修复它:
oops o;
std::function<void(GtkWidget*, GdkEvent*, gpointer)> f = …
Run Code Online (Sandbox Code Playgroud) 我想将Library cpp-netlib用于C++项目.因此我在自制软件的帮助下安装了boost库(操作系统是Mac OS X 10.8).然后我从项目主页下载了cpp-netlib,使用cmake为g ++创建了Makefile并成功应用了make."make test"通过了所有测试.然后我将cpp-netlib的include文件夹复制到boost目录中.
所以这就是麻烦开始的时候:我试图编译文档的第一个示例http-client,但无法使其工作.我用的时候
g++ test.cpp -o out -I/usr/local/Cellar/boost/1.53.0/include
-L/usr/local/Cellar/boost/1.53.0/lib
-lboost_system-mt -lboost_filesystem-mt -lboost_thread-mt
Run Code Online (Sandbox Code Playgroud)
我收到了这些链接器错误:
Undefined symbols for architecture x86_64:
"boost::network::uri::detail::parse(__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::network::uri::detail::uri_parts<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)", referenced from:
boost::network::uri::uri::parse() in ccs87Dq3.o
"boost::network::http::impl::normal_delegate::normal_delegate(boost::asio::io_service&)", referenced from:
boost::network::http::impl::connection_delegate_factory<boost::network::http::tags::http_async_8bit_udp_resolve>::new_connection_delegate(boost::asio::io_service&, bool, boost::optional<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::optional<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >)in ccs87Dq3.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit …
Run Code Online (Sandbox Code Playgroud) C++ 11中的以下代码:
auto function(X x, Y y) -> decltype(x + y)
{
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
等于C++ 14中的以下代码:
decltype(auto) function(X x, Y y)
{
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
但另外,decltype
在C++ 14中可以推断出没有规则的返回类型:
auto function()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
C++ 11中的以下代码:
auto function() -> int
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
等于C++ 03中的以下代码:
int function()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
C++ 11中的以下代码:
auto function(X x, Y y) -> decltype(x * …
Run Code Online (Sandbox Code Playgroud) 在我阅读C++参考时,我对这一段有疑问:
注意:C编程语言支持无序指定初始化,嵌套指定初始化,指定初始化器和常规初始化器的混合以及指定的数组初始化,但C++中不允许这样做.
是否有任何技术原因阻止C++支持无序指定初始化?
在HTML中,<bdo>
标记用于覆盖当前文本方向.
当我有<div>
标签时,我应该<bdo>
在里面使用标签吗?
<div><bdo dir="rtl">TEXT</bdo></div>
Run Code Online (Sandbox Code Playgroud)
或者我应该使用CSS类作为<div>
标记:
<div class="rtl-lang">TEXT</div>
Run Code Online (Sandbox Code Playgroud)
我的问题是:我<bdo>
什么时候应该使用标签?它会被弃用吗?
考虑这两个:
namespace X1
{
A operator "" _x(unsigned long long i) { return A{i}; }
};
namespace X2
{
B operator "" _x(unsigned long long i) { return B{i}; }
};
Run Code Online (Sandbox Code Playgroud)
该x
文本被定义了两次,但其中一人在规定namespace X1
而另一个定义namespace X2
.
根据C++标准,可以编译这段代码吗?
我知道override
上下文关键字是为了编写更安全的代码而引入的(通过检查virtual
具有相同签名的函数)但我感觉不太好,因为override
每次我想要覆盖一个时,我似乎都是多余的virtual
功能.
override
在99%的案例中不使用上下文关键字是不好的做法吗?为什么/什么时候我必须使用它(当我们错误地隐藏虚函数时,编译器警告是不够的)?
编辑:换句话说; override
在C++ 11 中使用contextual关键字有什么好处,而如果我们在C++ 03中错误地隐藏虚函数(不使用override
上下文关键字),我们总是有编译器警告?