std :: tolower和Visual Studio 2013 [英] std::tolower and Visual Studio 2013

查看:192
本文介绍了std :: tolower和Visual Studio 2013的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解如何使用std::tolower ...

I try to understand how to use std::tolower...

#include <iostream>
#include <string>
#include <algorithm>
#include <locale>

int main()
{
    std::string test = "Hello World";
    std::locale loc;
    for (auto &c : test)
    {
        c = std::tolower(c, loc);
    }

    std::transform(test.begin(), test.end(), test.begin(), ::tolower); // 1) OK
    std::transform(test.begin(), test.end(), test.begin(), std::tolower); // 2) Cryptic compile error
    std::transform(test.begin(), test.end(), test.begin(), static_cast<int(*)(int)>(std::tolower)); // 3) Cryptic compile error. Seems OK with other compilers though

    return 0;
}

所以:

  1. 为什么::tolower版本有效?
  2. 为什么std::tolower在std :: transform中不起作用?
  3. static_cast<int(*)(int)>(std::tolower))真正在试图做什么?为什么 它可用于GCC而不适用于Visual Studio 2013?
  4. 然后如何在std :: transform和Visual Studio 2013中使用std::lower?
  1. Why ::tolower version is working?
  2. Why std::tolower is not working in std::transform?
  3. What static_cast<int(*)(int)>(std::tolower)) really is trying to do? Why does it work with GCC and not with Visual Studio 2013?
  4. How could I use std::lower in std::transform with Visual Studio 2013 then?

推荐答案

首先,请注意,这些方法中的没有都以可移植的方式完成了正确的工作!问题是char可能是带符号的(通常是带符号的),但是tolower()的版本仅接受正值!那就是您真的想使用std::tolower()这样的东西:

First off, note, that none of these approaches does the right thing in a portable way! The problem is that char may be signed (and typically is) but the versions of tolower() only accept positive values! That is you really want to use std::tolower() using something like this:

std::transform(test.begin(), test.end(), test.begin(),
               [](unsigned char c) { return std::tolower(c); });

(或者,如果您对C ++ 03感到困惑,当然可以使用相应的函数对象).将std::tolower()(或::tolower())用作负值会导致未定义的行为.当然,这仅在签署了char的平台上才有意义,但是,这似乎是典型的选择.

(or, of course, using a corresponding function object if you are stuck with C++03). Using std::tolower() (or ::tolower() for that matter) with a negative value results in undefined behavior. Of course, this only matters on platform where char is signed which seems, however, to be the typical choice.

要回答您的问题:

  1. 当包含<cctype>时,通常会在名称空间std和全局名称空间中从标准C库获得各种函数和类型.因此,使用::tolower通常可以正常使用,但不能保证可以正常使用.
  2. 当包含<locale>时,有两个std::tolower版本可用,一个为int(*)(int),一个为char(*)(char, std::locale const&).仅使用std::tolower时,编译器通常无法确定要使用哪个.
  3. 由于std::tolower含糊不清,因此使用static_cast<int(*)(int)>(std::tolower)可以消除使用哪个版本的歧义.我不知道为什么将static_cast<...>()与VC ++一起使用会失败.
  4. 无论如何,都不应将std::tolower()与序列char一起使用,因为这将导致不确定的行为.在unsigned char上内部使用std::tolower使用功能对象.
  1. When including <cctype> you typically get the various functions and types from the standard C library both in namespace std as well as in the global namespace. Thus, using ::tolower normally works but isn't guaranteed to work.
  2. When including <locale>, there are two versions of std::tolower available, one as int(*)(int) and one as char(*)(char, std::locale const&). When using just std::tolower the compiler has generally no way to decide which one to use.
  3. Since std::tolower is ambiguous, using static_cast<int(*)(int)>(std::tolower) disambiguates which version to use. Why use of static_cast<...>() with VC++ fails, I don't know.
  4. You shouldn't use std::tolower() with a sequences of chars anyway as it will result in undefined behavior. Use a function object using std::tolower internally on an unsigned char.

值得注意的是,使用函数对象而不是函数指针通常要快很多,因为内联函数对象并不容易,而内联函数指针却不那么容易.在实际上知道函数的地方使用内联函数指针,编译器会变得更好,但是当代的编译器当然并不总是通过函数指针内联函数调用,即使所有上下文都在那里.

It is worth noting that using a function object rather than a function pointer is typically a lot faster because it is trivial to inline the function object but not as trivial to inline the function pointer. Compilers are getting better with inlining the use of function pointers where the function is actually known but contemporary compilers certainly don't always inline function calls through function pointers even if all the context would be there.

这篇关于std :: tolower和Visual Studio 2013的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆