0

次のコードを使用して、ポインターを文字列に変換し、文字列をポインターに戻そうとしています (レキシカル キャスト)。ポインターから文字列への変換は正常に機能しますが、その逆は機能しません。

なぜこれが起こるのですか?文字列をポインタに変換できる他の方法はありますか?

文字列の形式が正しくないために発生するエラーについては心配していません。ポインターに変換しようとしている文字列は、ポインターを文字列に変換することによって常に生成されます。

コードは次のとおりです。

//TB_ConvertToString.cpp

#include<iostream>
#include<cstdio>
#include<sstream>
#include<string>

//Functions to convert data types to and from strings   
template <typename T> std::string ToString ( T Number )
{
    std::stringstream ss;
    ss << Number;
    return ss.str();
};

template <typename T> 
T FromString ( const std::string &Text )
{
    std::stringstream ss(Text);
    T result;
    ss >> result;
    return result;
}
//-------------------------------------------------


using namespace std;

int main()
{
    int a =10;  
    int* p1 = &a;
    // this works------------
    string s1 = ToString<int *>(p1);
    printf("\n ptr: %s",s1.c_str());
    //----------------------

    //this gives compilation errors -----
    //int * p2 = FromString<int *>(s1);
    //printf("\n ptr: %p",p2);
    //----------------------


    cout<<"\n\n";
    return 0;
};

問題のセクションのコメントを外すと、次のコンパイル エラーが発生します。

nehak@Marvin:~/Desktop$ g++ TB_ConvertToString.cpp 
TB_ConvertToString.cpp: In function ‘T FromString(const string&) [with T = int*, std::string = std::basic_string<char>]’:
TB_ConvertToString.cpp:39:33:   instantiated from here
TB_ConvertToString.cpp:21:2: error: no match for ‘operator>>’ in ‘ss >> result’
TB_ConvertToString.cpp:21:2: note: candidates are:
/usr/include/c++/4.6/istream:122:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__istream_type& (*)(std::basic_istream<_CharT, _Traits>::__istream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:122:7: note:   no known conversion for argument 1 from ‘int*’ to ‘std::basic_istream<char>::__istream_type& (*)(std::basic_istream<char>::__istream_type&) {aka std::basic_istream<char>& (*)(std::basic_istream<char>&)}’
/usr/include/c++/4.6/istream:126:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__ios_type& (*)(std::basic_istream<_CharT, _Traits>::__ios_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>, std::basic_istream<_CharT, _Traits>::__ios_type = std::basic_ios<char>]
/usr/include/c++/4.6/istream:126:7: note:   no known conversion for argument 1 from ‘int*’ to ‘std::basic_istream<char>::__ios_type& (*)(std::basic_istream<char>::__ios_type&) {aka std::basic_ios<char>& (*)(std::basic_ios<char>&)}’
/usr/include/c++/4.6/istream:133:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:133:7: note:   no known conversion for argument 1 from ‘int*’ to ‘std::ios_base& (*)(std::ios_base&)’
/usr/include/c++/4.6/istream:169:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(bool&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:169:7: note:   no known conversion for argument 1 from ‘int*’ to ‘bool&’
/usr/include/c++/4.6/istream:173:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(short int&) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.6/istream:173:7: note:   no known conversion for argument 1 from ‘int*’ to ‘short int&’
/usr/include/c++/4.6/istream:176:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(short unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:176:7: note:   no known conversion for argument 1 from ‘int*’ to ‘short unsigned int&’
/usr/include/c++/4.6/istream:180:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(int&) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.6/istream:180:7: note:   no known conversion for argument 1 from ‘int*’ to ‘int&’
/usr/include/c++/4.6/istream:183:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:183:7: note:   no known conversion for argument 1 from ‘int*’ to ‘unsigned int&’
/usr/include/c++/4.6/istream:187:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:187:7: note:   no known conversion for argument 1 from ‘int*’ to ‘long int&’
/usr/include/c++/4.6/istream:191:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:191:7: note:   no known conversion for argument 1 from ‘int*’ to ‘long unsigned int&’
/usr/include/c++/4.6/istream:196:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:196:7: note:   no known conversion for argument 1 from ‘int*’ to ‘long long int&’
/usr/include/c++/4.6/istream:200:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:200:7: note:   no known conversion for argument 1 from ‘int*’ to ‘long long unsigned int&’
/usr/include/c++/4.6/istream:205:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(float&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:205:7: note:   no known conversion for argument 1 from ‘int*’ to ‘float&’
/usr/include/c++/4.6/istream:209:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(double&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:209:7: note:   no known conversion for argument 1 from ‘int*’ to ‘double&’
/usr/include/c++/4.6/istream:213:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long double&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:213:7: note:   no known conversion for argument 1 from ‘int*’ to ‘long double&’
/usr/include/c++/4.6/istream:217:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(void*&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
/usr/include/c++/4.6/istream:217:7: note:   no known conversion for argument 1 from ‘int*’ to ‘void*&’
/usr/include/c++/4.6/istream:241:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__streambuf_type*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>]
/usr/include/c++/4.6/istream:241:7: note:   no known conversion for argument 1 from ‘int*’ to ‘std::basic_istream<char>::__streambuf_type* {aka std::basic_streambuf<char>*}’
/usr/include/c++/4.6/bits/basic_string.tcc:998:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/istream.tcc:957:5: note: template<class _CharT2, class _Traits2> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, _CharT2*)
/usr/include/c++/4.6/bits/istream.tcc:925:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, _CharT&)
/usr/include/c++/4.6/istream:709:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned char&)
/usr/include/c++/4.6/istream:714:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char&)
/usr/include/c++/4.6/istream:756:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned char*)
/usr/include/c++/4.6/istream:761:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char*)
nehak@Marvin:~/Desktop$ 
4

4 に答える 4

4

問題は、実際には次の単純なテスト ケースに絞り込むことができます。

std::stringstream ss("0xbf845748");
int* p2;
ss >> p2;

>>ポインターを初期化するような演算子のオーバーロードがないため、これは機能しません。このポインターの抽出を機能させるにvoid*は、このアドレスを保持するのに十分な大きさの整数を使用するか、抽出してから、ポインターがこのアドレスを指すようにすることができますが、過負荷reinterpret_cast<T>にならないように注意してください。char*それは、あなたが今扱っている問題をさらに悪化させる可能性があるからです。

に格納されているアドレスを使用してポインターを初期化しようとするのstd::stringは、本当に悪い考えであることに注意してください。機能させることを決定する前に、それが本当に必要なものであることを確認してください。これを回避するためのもっと合理的な方法がある可能性が高いです。

于 2013-03-18T09:59:01.443 に答える
2

@LihO、ありがとう!それはうまくいきます。ただし、ポインタを抽出するときにstd::hexを使用する必要がありました。

    string s1 = "0x7fff3e8aee1c";
    stringstream ss;
    ss<<s1;
    long long unsigned int i;
    ss>>std::hex>>i;
    int * i_ptr=reinterpret_cast<int *>(i);
于 2013-03-18T10:17:46.033 に答える
2

問題は、どの型のポインタも暗黙的に にキャストできるが、void*どの型のポインタにもキャストvoid*できないことです。あなたの場合FromString、すべてのポインターに対して関数を特殊化する必要があります。このような

template <typename T> 
T FromString ( const std::string &Text,
    std::enable_if< ! std::is_pointer< T >::value >::type * = nullptr )
{
    std::stringstream ss(Text);
    T result;
    ss >> result;
    return result;
}

template <typename T> 
T FromString ( const std::string &Text,
    std::enable_if< std::is_pointer< T >::value >::type * = nullptr )
{
    std::stringstream ss(Text);
    void * result;
    ss >> result;
    return (T)result;
}
于 2013-03-18T10:08:25.857 に答える