string的隐式转换,以及sizeof, strlen

问题来源:http://cxwangyi.blogspot.com/2010/05/hadoop-pipes-is-incompatible-with.html

关键部分截取如下:

In your mapper you have the line:
      context.emit("", "apple/norange/0banana/tpapaya");
The signature for the emit method is:
      TaskContext::emit(const std::string&, const std::string&);

Since you pass the value as a string literal, C++ must convert it to an std::string. Following C++'s implict conversion rules, it does so using std::string::string(const char*), which as defined by the standard looks for the first occurence of a null character to determine the length of the string. So, when emit gets called, it is being invoked with an std::string whose last character is the 'e' in orange. Not Hadoop's fault at all. You'd get the same result if you passed that literal to any function that expects an std::string (or for that matter pretty much any function where all you passed was that literal). Try this:

   1: #include 
   2: #include 
   3: void print(const std::string& aString) {
   4: std::cout << aString;
   5: }
   6: int main(int argc, char** argv) {
   7: print("apple/norange/0banana/tpapaya");
   8: std::cout << std::endl;
   9: }
You'll get the same disappointing result. If you change your code as follows it'll work fine:
      void map(HadoopPipes::MapContext& context) {
      const char valueString[] = "apple/norange/0banana/tpapaya";
      context.emit("", std::string(valueString, sizeof(valueString) - 1));
      }
All this does is make sure you give it a string which is properly length terminated.

解说:我们需要改变string默认的隐式转换。
http://www.cplusplus.com/reference/string/string/string/
string ( const char * s, size_t n );
    
ntent is initialized to a copy of the string formed by the first n characters in the array of characters pointed by s.

string ( const char * s );
Content is initialized to a copy of the string formed by the null-terminated character sequence (C string) pointed by s. The length of the caracter sequence is determined by the first occurrence of a null character (as determined by traits.length(s)). This version can be used to initialize a string object using a string literal constant.

你可能感兴趣的:(string的隐式转换,以及sizeof, strlen)