Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.5k views
in Technique[技术] by (71.8m points)

c++ - How to emulate class template argument deduction pre-C++17?

I am working on removing sscanf() calls from a C++ codebase and replacing them with the std::stringstream implementation described here: https://www.quora.com/Is-there-a-C-alternative-to-sscanf . The relevant code is:

template<class Char> 
class imatch 
{ 
    const Char* s; 
public: 
    imatch(const Char* x) :s(x) {} 
     
    template<class Stream> 
    friend Stream& operator >> (Stream& st, const imatch& m) 
    { 
        std::basic_string<Char> x; 
        st >> x; //strip spaces, read chars up to space 
        if(x!=m.s) st.setstate(st.failbit); //set as "failure" a mismatch 
        return st; 
    } 
}; 

Then in my codebase:

std::stringstream ss("value = 15"); //the input 
 
int val=0; 
ss >> imatch("value") >> imatch("=") >> val; 
 
if(ss) 
{ std::cout << "read value = " << val << std::endl; } 
else 
{ std::cout << "read failed" << std::endl; }

This uses class template argument deduction in the constructor calls. It works great...in C++17. The problem is that this code needs to compile all the way back to RHEL6, which only supports -std=c++0x at best (a subset of C++11).

What is the most succinct way to write and use this class such that users can easily port their sscanf() calls to use it, without access to C++17?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A common workaround was to provide a make_xx function that can rely on traditional template argument deduction:

template <typename T>
imatch<T> make_imatch(const T* t) { 
    return imatch<T>(t);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...