- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在 Stackoverflow 上有几个与使用 {boost, std}::string_view
相关的问答,例如:
parsing from std::string into a boost::string_view using boost::spirit::x3重载 x3 的 move_to
namespace boost { namespace spirit { namespace x3 { namespace traits {
template <typename It>
void move_to(It b, It e, boost::string_view& v)
{
v = boost::string_view(&*b, e-b);
}
} } } }
parse into vector using boost::spirit::x3其中进一步提供了有关属性兼容性的信息
namespace boost { namespace spirit { namespace x3 { namespace traits {
template <>
struct is_substitute<raw_attribute_type,boost::string_view> : boost::mpl::true_
{};
} } } }
llonesmiz 在 wandbox 写了一个例子用 boost 1.64 编译, 但因 boost 1.67 而失败现在与
opt/wandbox/boost-1.67.0/gcc-7.3.0/include/boost/spirit/home/x3/support/traits/container_traits.hpp:177:15: error: 'class boost::basic_string_view<char, std::char_traits<char> >' has no member named 'insert'
c.insert(c.end(), first, last);
~~^~~~~~
我在项目中遇到了同样的错误。
问题也通过使用 std::string
引发即使明确使用 Sehe's as<> "directive" ,另见 wandbox :
#include <iostream>
#include <string>
#include <string_view>
namespace boost { namespace spirit { namespace x3 { namespace traits {
template <typename It>
void move_to(It b, It e, std::string_view& v)
{
v = std::string_view(&*b, e-b);
}
} } } } // namespace boost
#include <boost/spirit/home/x3.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits {
template <>
struct is_substitute<raw_attribute_type, std::string_view> : boost::mpl::true_
{};
} } } } // namespace boost
namespace parser
{
namespace x3 = boost::spirit::x3;
using x3::char_;
using x3::raw;
template<typename T>
auto as = [](auto p) { return x3::rule<struct _, T>{ "as" } = x3::as_parser(p); };
const auto str = as<std::string_view>(raw[ +~char_('_')] >> '_');
const auto str_vec = *str;
}
int main()
{
std::string input = "hello_world_";
std::vector<std::string_view> strVec;
boost::spirit::x3::parse(input.data(), input.data()+input.size(), parser::str_vec, strVec);
for(auto& x : strVec) { std::cout << x << std::endl; }
}
据我所知,问题始于 boost 1.65。发生了什么变化以及如何修复它?
最后,我对sehe提到的连续存储的要求有疑问: 我理解这个要求,但是解析器可以违反这个吗? - 在我看来,即使在回溯时解析器也必须失败,所以这不可能发生。通过使用error_handler,指向string_view 的内存存储地址最终在解析级别有效。我的结论是,只要引用在这种情况下的范围内,就可以使用 string_view,不是吗?
最佳答案
这里的问题似乎与 is_container
有关特点:
template <typename T>
using is_container = mpl::bool_<
detail::has_type_value_type<T>::value &&
detail::has_type_iterator<T>::value &&
detail::has_type_size_type<T>::value &&
detail::has_type_reference<T>::value>;
在 Qi 中,那将是专门化的:
template <> struct is_container<std::string_view> : std::false_type {};
但是在 X3 中,它开始成为模板别名,无法专门化。
这是一个棘手的问题,因为似乎根本没有自定义点可以让 X3 执行我们在这里需要的操作。
我试图深入挖掘。我还没有看到解决这个问题的“干净”方法。事实上,属性强制转换可以帮助,但是,如果您使用它来“缩短”导致匹配的启发式:
在这种情况下,我们可以将解析器的属性强制设置为特别是不兼容,这样事情就会开始起作用了。
move_to
这也是一个有争议的领域。只需添加重载,如:
template <typename It>
inline void move_to(It b, It e, std::string_view& v) {
v = std::string_view(&*b, std::distance(b,e));
}
不足以使其成为最佳重载。
基础模板是
template <typename Iterator, typename Dest>
inline void move_to(Iterator first, Iterator last, Dest& dest);
要真正让它坚持下去,我们需要特化。然而,特化和功能模板is not a good match .特别是,我们不能部分特化,因此我们最终将对模板参数进行硬编码:
template <>
inline void move_to<Iterator, std::string_view>(Iterator b, Iterator e, std::string_view& v) {
v = std::string_view(&*b, std::distance(b,e));
}
This is making me question whether
move_to
is "user-serviceable" at all, much likeis_container<>
above, it just seems not designed for extension.I do realize I've applied it in the past myself, but I also learn as I go.
而不是声明规则的属性 std::string_view
(将 X3 的类型魔法室留给“做
正确的
事情”),让我们将 raw[]
的预期结果刻在石头上。 (并让 X3 使用 move_to
完成其余的魔术):
namespace parser {
namespace x3 = boost::spirit::x3;
const auto str
= x3::rule<struct _, boost::iterator_range<Iterator> >{"str"}
= x3::raw[ +~x3::char_('_')] >> '_';
const auto str_vec = *str;
}
这行得通。查看它 Live On Wandbox
打印
hello
world
这看起来很脆弱。例如。如果你change Iterator
to char const*
它会坏的(或者,use std::string const
input = "hello_world_"
,但不是 both)。
这是一个更好的做法(我认为):
namespace boost { namespace spirit { namespace x3 {
template <typename Char, typename CharT, typename Iterator>
struct default_transform_attribute<std::basic_string_view<Char, CharT>, boost::iterator_range<Iterator>> {
using type = boost::iterator_range<Iterator>;
template <typename T> static type pre(T&&) { return {}; }
static void post(std::basic_string_view<Char, CharT>& sv, boost::iterator_range<Iterator> const& r) {
sv = std::basic_string_view<Char, CharT>(std::addressof(*r.begin()), r.size());
}
};
} } }
现在,唯一需要跳过的环节是规则声明中提到迭代器类型。你也可以隐藏它:
namespace parser {
namespace x3 = boost::spirit::x3;
template <typename It> const auto str_vec = [] {
const auto str
= x3::rule<struct _, boost::iterator_range<It> >{"str"}
= x3::raw[ +~x3::char_('_')] >> '_';
return *str;
}();
}
auto parse(std::string_view input) {
auto b = input.begin(), e = input.end();
std::vector<std::string_view> data;
parse(b, e, parser::str_vec<decltype(b)>, data);
return data;
}
int main() {
for(auto& x : parse("hello_world_"))
std::cout << x << "\n";
}
这立即表明它适用于非指针迭代器。
Note: for completeness you'd want to statically assert the iterator models the ContiguousIterator concept (c++17)
#include <iostream>
#include <string>
#include <string_view>
#include <boost/spirit/home/x3.hpp>
namespace boost { namespace spirit { namespace x3 {
template <typename Char, typename CharT, typename Iterator>
struct default_transform_attribute<std::basic_string_view<Char, CharT>, boost::iterator_range<Iterator>> {
using type = boost::iterator_range<Iterator>;
template <typename T> static type pre(T&&) { return {}; }
static void post(std::basic_string_view<Char, CharT>& sv, boost::iterator_range<Iterator> const& r) {
sv = std::basic_string_view<Char, CharT>(std::addressof(*r.begin()), r.size());
}
};
} } }
namespace parser {
namespace x3 = boost::spirit::x3;
template <typename It> const auto str_vec = [] {
const auto str
= x3::rule<struct _, boost::iterator_range<It> >{"str"}
= x3::raw[ +~x3::char_('_')] >> '_';
return *str;
}();
}
auto parse(std::string_view input) {
auto b = input.begin(), e = input.end();
std::vector<std::string_view> data;
parse(b, e, parser::str_vec<decltype(b)>, data);
return data;
}
int main() {
for(auto& x : parse("hello_world_"))
std::cout << x << "\n";
}
关于c++ - Spirit.X3 使用 string_view 和名为 'insert' 的成员编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50310015/
这个问题在这里已经有了答案: Is Git’s "master" branch name more than just a name? (3 个回答) What will break if I don
我使用了Plone实例文件夹的“bin /”目录中的“paster”命令来创建一个名为“MyApp”的plone应用程序(来自模板),该命令是: (from instance's root folde
我正在尝试覆盖 FOSUserBundle 的用户映射的两个属性。 use FOS\UserBundle\Model\User as BaseUser; ... use Symfony\Bridge\
工作通过 these posts让我认为我了解自我类型,至少在某种程度上。 所以我创建了一个按预期失败的例子: scala> trait A { val v = "a" } defined trait
我在 IntelliJ 中有一个 JavaFX Maven 项目,它使用 Hibernate。当应用程序启动时,我收到以下错误消息: No persistence provider for entit
我正在尝试构建一个数据透视表,并使用开源代码并摸索着这个函数。record[] 如何传递给这个函数?似乎没有经过或任何声明。怎么能直接来呢? 完整代码可以在这里找到https://github.com
我的应用程序有 abc.com 链接,这是一个主页和 abc.com/user123(有一个动态部分),这是一个用户登录的特定配置文件页面。 早些时候,我通过这样做实现了这一点: this.route
当我在使用 mac book pro 的 Android Studio 上设置 Flutter Sdk 路径时,我遇到错误 Flutter SDK 路径未给出(并且打开一个弹出窗口并显示消息“名为‘F
我刚刚设置了 Postgres 供我网络上的不同用户使用。每个用户都有自己的用户名/密码/数据库,但是当我连接到 Pg 时,我还可以看到一个“postgres”数据库(甚至可以创建表等)。我试图从公众
我正在尝试从 MySQL 数据库中获取一些数据。所以我要做的是: select * from my_table where 'to' ='0000-00-00 00:00:00'; 这给了我空集,但我
我有一个名为“索引”的表。我意识到这是 MySQL 中的关键字,想知道如何在查询中引用该表? 我的错误: #1064 - You have an error in your SQL syntax; c
我在机器 myuniversity.edu 上设置了一个远程 mysql 数据库服务器,服务器名为“localhost”。我在上面有一个名为“MyDatabase”的数据库。 I want to co
我正在尝试使用 Android NDK 构建应用程序。我已按照所有步骤操作,一切正常,正在制作 .so 文件。但是在 Eclipse 中,当我尝试清理项目时出现以下错误: The file does
我正在重写 UIImage 类方法 init(named:)。我的目标是能够检索图像的文件名。 代码看起来像这样: class UIImageWithFileName: UIImage { l
@ThreadSafe public class A { } 这个注解实际上使类线程安全还是只是为了提高可读性? 最佳答案 参见 @ThreadSafe Annotation : Place this
当我将第二个表(dtResult)添加到数据集时出现错误 名为“Table”的数据表已属于此数据集。 DataTable dtSession = new DataTable(); DataTable
这个问题可能看起来重复,但略有不同。在 SO 的所有其他问题中,我注意到他们注册了多条路线。但就我而言,我只有一条路线。 我正在创建 asp.net webapi(框架 4.5)并且在 Registe
我最近将 Microsoft.AspNet.WebApi.WebHost 添加到 MVC WebAPI 项目中,这将允许我使用 [Route("api/some-action")] 归因于我的行动。我
我有一个名为“异常”的命名空间的问题 让我们考虑以下示例标题: #include namespace exception { struct MyException : public std::e
我昨天安装了 Nuget 1.2,今天,当我尝试安装 Entity Framework 包时,我在包管理器控制台中遇到了以下问题: PM> install-package entityframewor
我是一名优秀的程序员,十分优秀!