设 ss 为 std::stringstream。如何为(ss<<some_type).str()指定一个概念是std::string?

Let ss be a std::stringstream. How to specify a concept for (ss<<some_type).str() is a std::string?

设 ss 为 std::stringstream。如何指定 (ss << some_type).str() 的概念是 std::string?

这是我目前的代码:

#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. 错误消息的第一部分如下:

<source>:25:5: error: no matching function for call to 'call'

    call("Hi");

    ^~~~

你不见了#include <sstream>

修复给出包含以下内容的错误消息:

<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>;

这告诉您 (ss << obj) 的计算结果为 std::ostream,它没有 .str() 成员。您只需要检查 ss<<a 编译,并且您已经知道 ss.str() 会产生一个字符串,因此您不需要在约束中使用它。

很遗憾,我对约束的了解还不够多,无法为您创建工作代码。

感谢 Mooing Duck 我能够获得代码 运行。 运行 代码如下:

#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