如何编码和超载返回自身的功能?C 17

How to code and overload the function that returns itself? C++17

本文关键字:功能 返回 超载 何编码 编码      更新时间:2023-10-16

使用MSVC最新(截至25Dec17)。

    template< typename T>
    auto out_ (const T & val_) 
    {
        // do something with val_
        // error: can not deduce auto from out_
        return out_;
    }

问题是如何编码,然后写上面的小"东西"的几个过载?

是的,它必须是MSVC和C 17。没有GCC 7.0.2也不会编译。Clang尚未尝试。

也许函子模式可能会有所帮助?

请建议...

我很惊讶您的lambda解决方案与G 一起使用。

的clang 投诉
 error: variable 'out_' declared with deduced type 'auto' cannot appear in its own initializer
 return out_ ;
        ^

我怀疑正确的clang 拒绝您的代码(错误的G 接受),但我不确定。

无论如何,我发现lambda返回自己很有趣的想法。

我提出了一个基于模板operator()的结构的非lambda(但我希望标准符合标准和便携式)解决方案,将其返回对象的引用。

我的意思是

struct outS
 {
   template <typename T>
   outS const & operator() (T const & t) const
    {
      std::cout << t;
      return *this;
    }
 };

因此您可以以身作则,

outS{}("Hello ")("from ")("GCC ")(__VERSION__)(" !");

std::endl的问题是不同的。

问题是将std::endl定义(请参阅CPP参考)为

template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& endl( std::basic_ostream<CharT, Traits>& os );

也就是说, std::endl是模板函数。

您可以写

std::cout << std::endl;

std::wcout << std::endl;

因为操作员<<选择std::endl的特定版本;但是您不能如下将其传递给outS

outS{}(std::endl);

因为outS无法选择std::endl的特定版本。

因此,您必须阐明它;要匹配std::endlstd::coutstd::endl的模板参数为charstd::char_traits<char>

所以你可以写(丑陋,我知道)

outS{}(std::endl<char, std::char_traits<char>>);

但是,如果您实现了基于struct的解决方案(outS),则可以添加endl()方法

outS const & endl () const
 {
   std::cout << std::endl;
   return *this;
 }

所以你可以写

outS{}.endl();

以下是一个完整的工作示例

#include <iostream>
struct outS
 {
   template <typename T>
   outS const & operator() (T const & t) const
    {
      std::cout << t;
      return *this;
    }
   outS const & endl () const
    {
      std::cout << std::endl;
      return *this;
    }
 };
int main()
 {
   outS{}("Hello ")("from ")("GCC ")(__VERSION__)(" !").endl();
 }

忘记模板。答案是Auto的 lambda:

#include <iostream>
    auto out_ = [] ( auto & val_) 
    {
        std::cout << val_;
        return out_ ;
    };
   int main()
   {
    out_("Hello ")("from ")("GCC ")(__VERSION__)(" !"); 
    // GCC can not compile this: ( std::endl );
   }

我并不感到惊讶,因为lambda被实施为函数。为什么GCC 7.0.2不能接受std :: endl,现在我没有时间破译了。

http://coliru.stacked-crooked.com/a/b85b5f89047b5828

至于std :: endl"问题"和 @max66解决方案,我确实认为C 20将具有更好的通用/模板lambdas,其中"自动"将表示"自动" ...

几年前,虽然专注于我的jQuery工作,但我可能已经发明了这个概念,我称其为"呼叫流"……这是有利的。关于它的文章很少。

,但是当时(C 11之前)实现非常类似于 @Max66解决方案。C 17使这个简单的单lambda(在我的回答中)成为一个相当优雅的解决方案,我敢写。

我不确定在这里提供我博客的链接是否可以...

https://dbj.org/callstream-project-euler/