草庐IT

c++ - 从 back_insert_iterator 中提取容器的 value_type 的特征类

coder 2024-02-02 原文

std::back_insert_iteratorvalue_type 等于 void,但它还有一个 protected 成员 container 包含指向底层 Container 的指针。我正在尝试编写一个 traits 类来提取容器的 value_type,如下所示:

#include <iterator>
#include <type_traits>
#include <vector>

template<class OutputIt>
struct outit_vt
:
    OutputIt
{
    using self_type = outit_vt<OutputIt>;
    using value_type = typename std::remove_pointer_t<decltype(std::declval<self_type>().container)>::value_type;
};

int main()
{
    std::vector<int> v;
    auto it = std::back_inserter(v);
    static_assert(std::is_same<outit_vt<decltype(it)>::value_type, int>::value, "");
}

Live Example

但是,这(或多或少是意料之中的)会遇到不完整的类型错误。为了提取容器的 value_type 是否有任何办法?

最佳答案

@Rapptz 的答案是正确的,但对于通用代码(即当先验不清楚是否处理原始 T*back_insert_iterator 或标准库的其他输出迭代器之一时),更多系统的方法是必要的。

为此,下面定义了一个类模板 output_iterator_traits在用户定义的 namespace xstd 中.

#include <iterator>             // iterator, iterator_traits, input_iterator_tag, output_iterator_tag, random_access_iterator_tag
                                // back_insert_iterator, front_insert_iterator, insert_iterator, ostream_iterator, ostreambuf_iterator
#include <memory>               // raw_storage_iterator

namespace xstd {

template<class T>
struct output_iterator_traits
:
        std::iterator_traits<T>
{};

template< class OutputIt, class T>
struct output_iterator_traits<std::raw_storage_iterator<OutputIt, T>>
:
        std::iterator<std::output_iterator_tag, T>
{};

template<class Container>
struct output_iterator_traits<std::back_insert_iterator<Container>>
:
        std::iterator<std::output_iterator_tag, typename Container::value_type>
{};

template<class Container>
struct output_iterator_traits<std::front_insert_iterator<Container>>
:
        std::iterator<std::output_iterator_tag, typename Container::value_type>
{};

template<class Container>
struct output_iterator_traits<std::insert_iterator<Container>>
:
        std::iterator<std::output_iterator_tag, typename Container::value_type>
{};

template <class T, class charT, class traits>
struct output_iterator_traits<std::ostream_iterator<T, charT, traits>>
:
        std::iterator<std::output_iterator_tag, T>
{};

template <class charT, class traits>
struct output_iterator_traits<std::ostreambuf_iterator<charT, traits>>
:
        std::iterator<std::output_iterator_tag, charT>
{};

} // namespace xstd

非专用版本简单地继承自std::iterator_traits<T> , 但对于 <iterator> 中定义的 6 个输出迭代器和 <memory> header ,特化继承自 std::iterator<std::output_iterator_tag, V>其中 V是作为迭代器的 operator=(const V&) 的参数出现的类型.

对于插入迭代器,这对应于 typename Container::value_type , 对于原始存储迭代器到 T , 以及 ostreamostreambuf T 的迭代器和 charT , 分别。

形式的通用算法

template<class InputIt, class OutputIt>
auto my_fancy_algorithm(InputIt first, InputIt last, OutputIt dest)
{
     using T = typename xstd::output_iterator_traits<OutputIt>::value_type;
     for (; first != last; ++first) {
         // ... construct arguments from *first
         *dest++ = T{ /* arguments */ };
     }
}

然后将透明地使用原始指针和标准库的输出迭代器。

关于c++ - 从 back_insert_iterator 中提取容器的 value_type 的特征类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29065760/

有关c++ - 从 back_insert_iterator 中提取容器的 value_type 的特征类的更多相关文章

  1. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. ruby-on-rails - Rails 单表继承 : How to override the value written to the type field - 2

    在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型

  5. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  6. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  7. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

  8. ruby-on-rails - 为什么方法 column_types 在 Rails 5.0 中未定义? - 2

    我正在为一个类赋值,它在rspec测试中使用了column_types方法。it"Userdatabasestructureinplace"doexpect(User.column_names).toinclude"password_digest","username"expect(User.column_types["username"].type).toeq:stringexpect(User.column_types["password_digest"].type).toeq:stringexpect(User.column_types["created_at"].type).t

  9. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  10. ruby - 如何在ruby中提取方括号内的内容 - 2

    我正在尝试提取方括号内的内容。到目前为止,我一直在使用它,它有效,但我想知道我是否可以直接在正则表达式中使用某些东西,而不是使用这个删除功能。a="Thisissuchagreatday[coolawesome]"a[/\[.*?\]/].delete('[]')#=>"coolawesome" 最佳答案 差不多。a="Thisissuchagreatday[coolawesome]"a[/\[(.*?)\]/,1]#=>"coolawesome"a[/(?"coolawesome"第一个依赖于提取组而不是完全匹配;第二个利用前瞻和

随机推荐