小编aki*_*kim的帖子

basic_string <CharT>与CharT*

这是一个FAQ,但我找不到令人满意的答案.在我的项目中,我们支持std::string并且现在还必须支持宽字符串.所以我们想要转移basic_string,但是,事情就会停止运行,并且需要明确地拼写参数:

#include <string>

template <typename CharT, typename Traits, typename Allocator>
void
foo(const std::basic_string<CharT, Traits, Allocator>&)
{}

template void foo(const std::string&);

// template void
// foo<char, std::char_traits<char>, std::allocator<char>>(const std::string&);

void bar(const std::string& s)
{}

int main()
{
  bar("abc");
  foo<char, std::char_traits<char>, std::allocator<char>>("def");
  foo("def");
}
Run Code Online (Sandbox Code Playgroud)

好吧,由于众所周知的原因,它失败了:

clang++-mp-3.5 -Wall -std=c++11 foo.cc 
foo.cc:20:3: error: no matching function for call to 'foo'
  foo("def");
  ^~~
foo.cc:5:1: note: candidate template ignored: could not match
      'basic_string<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2>'
      against 'char const[4]'
foo(const std::basic_string<CharT, Traits, Allocator>&) …
Run Code Online (Sandbox Code Playgroud)

c++ templates stdstring c++11 type-deduction

3
推荐指数
1
解决办法
515
查看次数

编译器强制语义类型

假设我有一个代表自动机的类,其状态为编号(using state_t = unsigned),其过渡也编号(using transition_t = unsigned).当然,在某些时候我最终搞乱,因为有些电话transition_tstate_t属于同一类型,所以编译器不执行(语义)类型的安全性.通过使用由tag(struct transition_tag {}; struct state_tag {};)模板化的小类,这很容易解决,所以现在transition_tstate_t不兼容,好!

/// Lightweight state/transition handle (or index).
template <typename Tag>
struct index_t_impl
{
  using index_t = unsigned;

  constexpr index_t_impl(index_t i)
    : s{i}
  {}

  // Disallow index1_t i{index2_t{42}};
  template <typename T>
  index_t_impl(index_t_impl<T> t) = delete;

  bool operator==(index_t_impl t) const
  {
    return s == t.s;
  }

  // Disallow index1_t{42} ==  index2_t{42};
  template <typename T>
  bool operator==(index_t_impl<T> t) …
Run Code Online (Sandbox Code Playgroud)

c++ types stl type-safety c++14

3
推荐指数
1
解决办法
190
查看次数

Boost.x3:属性在备选方案之间累积

我有一个用于解析标识符的解析器foo, bar, baz和一个用于解析嵌套标识符的解析器,foo::bar, foo::bar.baz, foo::bar.baz.baham 它们都解析为相同的ast结构,如下所示:

struct identifier : x3::position_tagged{
    std::vector <std::string> namespaces;
    std::vector <std::string> classes;
    std::string identifier;

};
Run Code Online (Sandbox Code Playgroud)

解析器identifier看起来像这样:

#define VEC_ATR x3::attr(std::vector<std::string>({})) //ugly hack

auto const identifier_def =
                VEC_ATR
                >> VEC_ATR
                >> id_string;
Run Code Online (Sandbox Code Playgroud)

对于nested_identifier这样的:

auto const nested_identifier_def =
        x3::lexeme[
                (+(id_string >> "::") >> +(id_string >> ".") > id_string)
                | (+(id_string >> "::") >> VEC_ATR > id_string)
                | (VEC_ATR >> +(id_string >> ".") > id_string)
                | identifier

        ];
Run Code Online (Sandbox Code Playgroud)

我知道这个宏让我感到羞耻.标识符解析器工作正常,但 nested_identifier有一个奇怪的行为,如果我尝试解析像foo::bar::baz落在了解析器的AST对象,拥有所有的命名空间,在这种情况下 …

c++ parsing boost-spirit boost-spirit-x3

3
推荐指数
1
解决办法
456
查看次数

过滤范围,lambdas和is_sorted

这是我对过滤迭代器的一个问题的精简版本(所以没有必要让我以不同的方式重写它以避免过滤器).奇怪的是,在实际代码中is_sorted似乎只有问题,其他用途似乎工作正常.

#include <vector>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm_ext/is_sorted.hpp>

int main(int argc, const char* argv[])
{
  using namespace boost::adaptors;
  std::vector<int> all = {1,2,3,4,5,6,7,8,9};
  auto some = all | filtered([] (int i) { return i % 2; });
  return boost::is_sorted(some);
}
Run Code Online (Sandbox Code Playgroud)

这无法使用Clang ++ 3.5和G ++ 4.9进行编译(在Mac OS X上,最新):

$ clang++-mp-3.5 -std=c++11 -isystem /opt/local/include/ foo.cc
In file included from foo.cc:3:
In file included from /opt/local/include/boost/range/algorithm_ext/is_sorted.hpp:18:
/opt/local/include/boost/detail/is_sorted.hpp:25:28: error: object of type
      'boost::filter_iterator<(lambda at foo.cc:9:30), std::__1::__wrap_iter<int
      *> >' cannot be assigned because its copy …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11 boost-range

2
推荐指数
1
解决办法
1210
查看次数

为什么我不能在initializer_list上使用operator%?

在成员资格测试频繁的算法中,我真的很想念infix∈运算符,我喜欢使用%运算符.它适用于常规容器,但由于某种原因clang和gcc拒绝初始化列表.毫无疑问,他们是"正确的",因为标准肯定会拒绝这一点.但为什么?

#include <initializer_list>
#include <iostream>
#include <vector>

/// Whether e ? m.
template <typename T, typename U>
inline bool
in(const U& k, const std::initializer_list<T>& m)
{
  return std::find(begin(m), end(m), k) != std::end(m);
}

/// Whether e ? m.
template <typename T, typename U>
inline bool
operator%(const U& k, const std::initializer_list<T>& m)
{
  return in(k, m);
}

/// Whether e ? m.
template <typename T, typename U>
inline bool
operator%(const U& k, const std::vector<T>& m)
{
  return in(k, m);
}

int …
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading initializer-list c++11

2
推荐指数
1
解决办法
287
查看次数