如何模拟 class C++17 之前的模板参数推导?
How to emulate class template argument deduction pre-C++17?
我正在努力从 C++ 代码库中删除 sscanf()
调用,并将其替换为此处描述的 std::stringstream
实现:https://www.quora.com/Is-there-a-C-alternative-to-sscanf。相关代码为:
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;
}
};
然后在我的代码库中:
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; }
这在构造函数调用中使用了 class 模板参数推导。它工作得很好......在 C++17 中。问题是这段代码需要一直编译回 RHEL6,RHEL6 最多只支持 -std=c++0x
(C++11 的一个子集)。
编写和使用此 class 的最简洁方法是什么,以便用户可以轻松移植他们的 sscanf()
调用来使用它,而无需访问 C++17?
一个常见的解决方法是提供一个 make_xx
可以依赖传统模板参数推导的函数:
template <typename T>
imatch<T> make_imatch(const T* t) {
return imatch<T>(t);
}
我正在努力从 C++ 代码库中删除 sscanf()
调用,并将其替换为此处描述的 std::stringstream
实现:https://www.quora.com/Is-there-a-C-alternative-to-sscanf。相关代码为:
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;
}
};
然后在我的代码库中:
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; }
这在构造函数调用中使用了 class 模板参数推导。它工作得很好......在 C++17 中。问题是这段代码需要一直编译回 RHEL6,RHEL6 最多只支持 -std=c++0x
(C++11 的一个子集)。
编写和使用此 class 的最简洁方法是什么,以便用户可以轻松移植他们的 sscanf()
调用来使用它,而无需访问 C++17?
一个常见的解决方法是提供一个 make_xx
可以依赖传统模板参数推导的函数:
template <typename T>
imatch<T> make_imatch(const T* t) {
return imatch<T>(t);
}