尝试将 std::string vector 转换为 const char* vector :
#include <algorithm>
#include <functional>
#include <string>
#include <vector>
int main(int argc, char** argv)
{
std::vector<std::string> values;
values.push_back("test1");
values.push_back("test2");
values.push_back("test3");
std::vector<const char*> c_values(values.size());
std::transform(values.begin(), values.end(), c_values.begin(), std::mem_fn(&std::string::c_str));
std::transform(values.begin(), values.end(), c_values.begin(), std::bind(&std::string::c_str, std::placeholders::_1));
std::transform(values.begin(), values.end(), c_values.begin(), [](const std::string& str) { return str.c_str(); });
return 0;
}
使用 g++ (4.7.2) 编译时,所有三个选项都可以正常编译和链接。使用 clang 编译时,选项 1 和 2 无法链接,生成:
$ clang -std=c++11 -stdlib=libc++ -lc++ stringtransform.cpp
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::c_str() const", referenced from:
_main in stringtransform-ff30c1.o
ld: symbol(s) not found for architecture x86_64
我发现如果我希望它使用 g++ 和 clang 跨平台正确链接,我需要使用 lambda 版本(选项 3)。我是否遇到了链接器错误或 clang 的 C++11 支持漏洞,或者我调用 mem_fn() 和 bind() 版本的方式有问题?
编辑:
错误仍然存在于最新的 Xcode(6.3.2,clang 版本 6.1.0:
$ clang -v
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
最佳答案
这似乎是自 LLVM 3.6.0 以来 libc++ 版本中的一个错误
我猜他们没有导出 std::string::c_str()来自他们的 DSO 的符号,因此该符号不是全局的,无法链接到。
&string::c_str指向成员函数的指针会对该函数的符号产生依赖性,链接器无法解析该依赖性,因为符号的定义不是全局的。它有时在优化时起作用,因为 c_str()函数被内联,不需要符号的外部定义。
您可以通过在代码中自己实例化该函数来解决此问题:
#ifdef _LIBCPP_VERSION
template const char* std::string::c_str() const;
#endif
但是您应该意识到您的代码有问题。选项 1 和 2 不保证适用于任何标准库实现:
std::mem_fn(&std::string::c_str)
std::bind(&std::string::c_str, std::placeholders::_1)
对于非虚拟成员函数,如 std::basic_string::c_str()标准库可以自由定义额外的重载,或使用与标准中指定的签名不同的签名。这意味着任何尝试做 &std::a_class::a_nonvirtual_member_function是不可移植的,并且可能是一个错误。
例如,许多执行 &std::vector<X>::push_back 的 C++98 代码在 C++11 中停止编译,因为它现在是一个重载函数(有一个重载采用 const 左值引用和一个重载采用右值引用)。
这个具体示例可能会在实践中起作用,因为没有实现重载 std::basic_string::c_str或者给它一个有趣的签名。
lambda 函数很好,因为它不获取成员函数的地址,它只是调用它:
[](const std::string& str) { return str.c_str(); }
这样编译器就可以使用重载决策找到函数,而不是通过指向成员函数的可疑指针。
关于c++ - Clang:将 bind 或 mem_fn 与 string::c_str 和 transform 结合使用时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27680418/
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
在Ruby1.9.3(可能还有更早的版本,不确定)中,我试图弄清楚为什么Ruby的String#split方法会给我某些结果。我得到的结果似乎与我的预期相反。这是一个例子:"abcabc".split("b")#=>["a","ca","c"]"abcabc".split("a")#=>["","bc","bc"]"abcabc".split("c")#=>["ab","ab"]在这里,第一个示例返回的正是我所期望的。但在第二个示例中,我很困惑为什么#split返回零长度字符串作为返回数组的第一个值。这是什么原因呢?这是我所期望的:"abcabc".split("a")#=>["bc"
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf
我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension