问题
Let ss be a std::stringstream. How to specify a concept for (ss << some_type).str() is a std::string?
Here is the code I have so far:
#include <iostream>
#include <sstream>
namespace detail {
template< class T, class U >
concept SameHelper = std::is_same_v<T, U>;
}
template< class T, class U >
concept same_as = detail::SameHelper<T, U> && detail::SameHelper<U, T>;
template<typename T>
concept ssToStr = requires(T a, std::stringstream ss) {
{ (ss << a).str() } -> same_as<std::string>;
};
void call(ssToStr auto obj)
{
std::stringstream ss;
std::cout << (ss << obj).str() << std::endl;
}
int main()
{
call("Hi");
return 0;
}
You can check online that the code does not compile. The first part of the error messages reads:
<source>:25:5: error: no matching function for call to 'call'
call("Hi");
^~~~
回答1:
You're missing #include <sstream>
Fixing that gives the error message that contains:
<source>:14:17: note: because '(ss << a).str()' would be invalid: no member named 'str' in 'std::basic_ostream<char>'
{ (ss << a).str() } -> same_as<std::string>;
Which tells you that (ss << obj)
evaluates to a std::ostream
, which does not have a .str()
member. All you have to check is that ss<<a
compiles, and you already know that ss.str()
results in a string, so you don't need that in your constraint.
Unfortunately, I don't know enough about constraints to create the working code for you.
回答2:
Thanks to Mooing Duck I was able to get the code running. The running code reads:
#include <iostream>
#include <sstream>
template<typename T>
concept ssToStr = requires(T a, std::stringstream ss) {
{ ss << a };
};
void call(ssToStr auto obj)
{
std::stringstream ss;
ss << obj;
std::cout << ss.str() << std::endl;
}
int main()
{
call("Hi");
return 0;
}
You can run the code online
来源:https://stackoverflow.com/questions/60552631/let-ss-be-a-stdstringstream-how-to-specify-a-concept-for-sssome-type-str