使用Boost语言环境/ ICU,我为使用Mingw时将非ASCII字符输出到Windows控制台(cmd)的问题创建了一个解决方案。函数模板上的C++编译器优化返回参数
现在,我决定使用Visual Studio进行测试,结果发现使用std::locale::global(std::local(""))
将在cmd上产生正确的非ASCII输出,因此不需要我的解决方案。
现在,代码#error
在VS上,但我希望它更便携,即在VS和Mingw上使用该代码,但它没有对VS做任何事情。
显而易见的解决方案是在预处理,这样的事情(简体,我要离开了这样的东西do {} while(0)
):
#if defined(_MSC_VER)
#define SOME_HOPEFULLY_UNIQUE_PREFIX_CONVERT_OUTPUT(x) x
#else
#define SOME_HOPEFULLY_UNIQUE_PREFIX_CONVERT_OUTPUT(x) ConvertOuput(x)
#endif
然后我想,如果我能实现与函数模板相同的结果,只是返回了它的论点。事情是这样的:
template <typename T>
T ConvertOutput(T t)
{
return t;
}
与char*
一个简单的测试就如预期(64位版本配置上MSVC社区2015年),到ConvertOutput()
呼叫被省略掉:
lea rdx,[string "teste" (013F79761Ch)]
mov rcx,qword ptr [__imp_std::cout (013F797178h)]
call std::operator<<<std::char_traits<char> > (013F791690h)
mov dl,0Ah
mov rcx,rax
call std::operator<<<std::char_traits<char> > (013F791870h)
但同样简单的测试与std::string
显示,虽然我们获得RVO,但仍有一个临时搭建,并致电ConvertOutput()
:
124: std::string b1{"teste2"};
mov qword ptr [rsp+88h],0Fh
mov qword ptr [rsp+80h],0
mov byte ptr [b1],0
mov r8d,6
lea rdx,[string "teste2" (013F127624h)]
lea rcx,[b1]
call std::basic_string<char,std::char_traits<char>,
std::allocator<char> >::assign (013F1210C0h)
nop
125: auto b2 = ConvertOutput(b1);
mov qword ptr [rsp+38h],0Fh
mov qword ptr [rsp+30h],0
mov byte ptr [rsp+20h],0
or r9,0FFFFFFFFFFFFFFFFh
xor r8d,r8d
lea rdx,[b1]
lea rcx,[rsp+20h]
call std::basic_string<char,std::char_traits<char>,
std::allocator<char> >::assign (013F1211F0h)
lea rdx,[rsp+20h]
lea rcx,[b2]
call ConvertOutput<std::basic_string<char,std::char_traits<char>,
std::allocator<char> > > (013F124090h)
nop
我有一些希望,编译器,知道所有ConvertOuput()
所做的就是返回它的参数,也可以在此停止。我意识到这可能是不明智的,因为任意T
的副本可能会有一些期望的副作用(?),但由于实例化发生在std::string
,我预计编译器会有更多的摆动空间,std
类。
专业ConvertOutput()
为std::string
发表了类似的结果 - 暂时消失如果ConvertOutput()
需要一个参考,但电话仍然存在。
作为最后的尝试,我重载ConvertOutput()
这样的:
template <typename CharT>
CharT const* ConvertOutput(std::basic_string<CharT> const &t)
{
cout << "Ref: " << t << '\n';
return t.c_str();
}
,我终于得到了我所期望的行为,包括ConvertOutput()
呼叫的省音/内联:
132: std::string b1{"teste2"};
mov qword ptr [rsp+40h],0Fh
mov qword ptr [rsp+38h],0
mov byte ptr [b1],0
mov r8d,6
lea rdx,[string "teste2" (013F697624h)]
lea rcx,[b1]
call std::basic_string<char,std::char_traits<char>,
std::allocator<char> >::assign (013F6910C0h)
nop
133: auto b2 = ConvertOutput(b1);
lea rdx,[string "Ref: " (013F697730h)]
mov rcx,qword ptr [__imp_std::cout (013F697178h)]
call std::operator<<<std::char_traits<char> > (013F691690h)
mov rcx,rax
lea rdx,[b1]
call std::operator<<<char,std::char_traits<char>,
std::allocator<char> > (013F691A30h)
mov rcx,rax
mov dl,0Ah
call std::operator<<<std::char_traits<char> > (013F691870h)
lea rdx,[b1]
cmp qword ptr [rsp+40h],10h
cmovae rdx,qword ptr [b1]
我可以没有办法像模板一样获得与预处理器宏相同的效果,至少不是没有相当多的注意事项。
我错了吗?有没有一种方法(简单或其他)来实现这一点与模板,没有重载/专门针对每个使用的类型?
为什么需要这个? – Barry
@Barry我需要在mingw上的转换代码在Windows控制台上输出像“Opção”这样的字符串,并且我想在VS上使用相同的客户端代码(除了不需要转换任何内容外),因此需要一些能够返回收到的参数的东西。 – PCaetano