- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我的代码中有字符串标签,这些标签被转换为数字并用于在标签-值结构中搜索值。
我有这样的事情:
void foo()
{
type value = search("SomeTag");
}
搜索的定义如下:
type search(const char* tag)
{
return internal_search(toNumber(tag));
}
因为所有时间标签在编译时都是恒定的,所以我想从搜索函数中删除将标签转换为数字的调用。我知道可以在编译时使用模板( http://en.wikipedia.org/wiki/Compile_time_function_execution )执行一些简单的函数,但我不知道如何遍历以空结尾的字符串并将中间值保留在模板中。你能给出一个简单的例子,它迭代一个以空结尾的字符串并将字符添加到一个公共(public)变量中吗?
最佳答案
听起来你想要的是Boost . MPL的boost::mpl::string
.在编译时使用 mpl::fold
编写元函数以将 mpl::string
转换为整数类型或多或少是微不足道的。 (如果字符串文字不代表有效的整数值,则编译失败)。
编辑:
我不完全确定你在寻找什么,所以这里实际上是两个不同的答案,具体取决于解释:
IF 您正在寻找的是编译时字符串到整数值的转换(例如,” 425897"
可以在编译时被识别为整数常量425897
),然后可以按照我的建议使用Boost.MPL:
#include <cstddef>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/char.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/negate.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/reverse_fold.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/vector.hpp>
namespace details
{
namespace mpl = boost::mpl;
typedef mpl::vector10<
mpl::char_<'0'>, mpl::char_<'1'>, mpl::char_<'2'>, mpl::char_<'3'>,
mpl::char_<'4'>, mpl::char_<'5'>, mpl::char_<'6'>, mpl::char_<'7'>,
mpl::char_<'8'>, mpl::char_<'9'>
> valid_chars_t;
template<typename IntegralT, typename PowerT>
struct power_of_10;
template<typename IntegralT, std::size_t Power>
struct power_of_10<IntegralT, mpl::size_t<Power> > : mpl::times<
power_of_10<IntegralT, mpl::size_t<Power - 1u> >,
mpl::integral_c<IntegralT, 10>
> { };
template<typename IntegralT>
struct power_of_10<IntegralT, mpl::size_t<1u> >
: mpl::integral_c<IntegralT, 10>
{ };
template<typename IntegralT>
struct power_of_10<IntegralT, mpl::size_t<0u> >
: mpl::integral_c<IntegralT, 1>
{ };
template<typename IntegralT, typename StringT>
struct is_negative : mpl::and_<
boost::is_signed<IntegralT>,
boost::is_same<
typename mpl::front<StringT>::type,
mpl::char_<'-'>
>
> { };
template<typename IntegralT, typename StringT>
struct extract_actual_string : mpl::eval_if<
is_negative<IntegralT, StringT>,
mpl::pop_front<StringT>,
mpl::identity<StringT>
> { };
template<typename ExtractedStringT>
struct check_valid_characters : boost::is_same<
typename mpl::find_if<
ExtractedStringT,
mpl::not_<mpl::contains<valid_chars_t, mpl::_> >
>::type,
typename mpl::end<ExtractedStringT>::type
> { };
template<typename ExtractedStringT>
struct pair_digit_with_power : mpl::first<
typename mpl::reverse_fold<
ExtractedStringT,
mpl::pair<mpl::vector0<>, mpl::size_t<0> >,
mpl::pair<
mpl::push_back<
mpl::first<mpl::_1>,
mpl::pair<mpl::_2, mpl::second<mpl::_1> >
>,
mpl::next<mpl::second<mpl::_1> >
>
>::type
> { };
template<typename IntegralT, typename ExtractedStringT>
struct accumulate_digits : mpl::fold<
typename pair_digit_with_power<ExtractedStringT>::type,
mpl::integral_c<IntegralT, 0>,
mpl::plus<
mpl::_1,
mpl::times<
mpl::minus<mpl::first<mpl::_2>, mpl::char_<'0'> >,
power_of_10<IntegralT, mpl::second<mpl::_2> >
>
>
> { };
template<typename IntegralT, typename StringT>
class string_to_integral_impl
{
BOOST_MPL_ASSERT((boost::is_integral<IntegralT>));
typedef typename extract_actual_string<
IntegralT,
StringT
>::type ExtractedStringT;
BOOST_MPL_ASSERT((check_valid_characters<ExtractedStringT>));
typedef typename accumulate_digits<
IntegralT,
ExtractedStringT
>::type ValueT;
public:
typedef typename mpl::eval_if<
is_negative<IntegralT, StringT>,
mpl::negate<ValueT>,
mpl::identity<ValueT>
>::type type;
};
}
template<typename IntegralT, typename StringT>
struct string_to_integral2
: details::string_to_integral_impl<IntegralT, StringT>::type
{ };
template<typename IntegralT, int C0, int C1 = 0, int C2 = 0,
int C3 = 0, int C4 = 0, int C5 = 0, int C6 = 0, int C7 = 0>
struct string_to_integral : string_to_integral2<
IntegralT,
boost::mpl::string<C0, C1, C2, C3, C4, C5, C6, C7>
> { };
用法如下:
type search(int tag) { /*impl... */ }
void foo()
{
type value = search(string_to_integral<int, '4258','97'>::value);
}
// OR, if you still want to maintain the separation
// between `search` and `internal_search`
type internal_search(int tag) { /*impl... */ }
template<typename TagStringT>
type search()
{
return internal_search(string_to_integral2<int, TagStringT>::value);
}
void foo()
{
typedef boost::mpl::string<'4258','97'> tag_t;
type value = search<tag_t>();
}
实现了对负数的支持,不支持溢出检测(但您的编译器可能会给出警告)。
IF 您正在寻找的是编译时字符串到整数值的映射(例如,” SomeTag"
可以在编译时被识别为整数常量425897
),那么Boost.MPL 仍然可以解决问题,但是在编译时必须知道所有字符串到整数值的映射时间并集中注册:
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/void.hpp>
namespace details
{
namespace mpl = boost::mpl;
typedef mpl::map<
mpl::pair<
mpl::string<'Some','Tag'>,
mpl::integral_c<int, 425897>
>,
mpl::pair<
mpl::string<'Some','Othe','rTag'>,
mpl::integral_c<int, -87>
>,
mpl::pair<
mpl::string<'AnUn','sign','edTa','g'>,
mpl::integral_c<unsigned, 7u>
>
> mappings_t;
template<typename StringT>
struct map_string_impl
{
typedef typename mpl::at<
mappings_t,
StringT
>::type type;
BOOST_MPL_ASSERT_NOT((boost::is_same<type, mpl::void_>));
};
}
template<typename StringT>
struct map_string2 : details::map_string_impl<StringT>::type { };
template<int C0, int C1 = 0, int C2 = 0, int C3 = 0,
int C4 = 0, int C5 = 0, int C6 = 0, int C7 = 0>
struct map_string : map_string2<
boost::mpl::string<C0, C1, C2, C3, C4, C5, C6, C7>
> { };
用法如下:
type search(int tag) { /*impl... */ }
void foo()
{
type value = search(map_string<'Some','Tag'>::value);
}
// OR, if you still want to maintain the separation
// between `search` and `internal_search`
type internal_search(int tag) { /*impl... */ }
template<typename TagStringT>
type search()
{
return internal_search(map_string2<TagStringT>::value);
}
void foo()
{
typedef boost::mpl::string<'Some','Tag'> tag_t;
type value = search<tag_t>();
}
mappings_t
是需要进行编辑以维护您的字符串到整数值的映射,并且如所示,映射的整数值不必都是相同的基础类型。
在任何一种情况下,因为映射是在编译时完成的,所以 search
/internal_search
(真正的实现采用 int
) 可以将整数值作为模板参数而不是函数参数,如果这样做对其实现有意义的话。
希望这能回答您的问题。
关于C++编译时函数执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5869442/
是否有任何库或框架旨在促进从另一种成熟的编程语言中构建项目? 在 C++、java 等编程语言中指定逻辑、集合和复杂规则非常容易,但在 Makefile 中完成这些事情似乎是一场艰苦的战斗。我还没有深
我有这段代码可以用 clang 编译得很好(即使使用 -Weverything),但是 gcc 会发出错误。 #include #include #include using namespace
我有以下 block 头文件 BKE_mesh.h: /* Connectivity data */ typedef struct IndexNode { struct IndexNode *
我在我的一个项目中遇到了一个奇怪的问题。我的代码库依赖于一个外部库,其中包含一个名为 Dataset 的类. Dataset类私有(private)继承自 std::vector (其中 Sample
当使用 gcc、g++ 或 make 在终端中编译一个小型 C 或 C++ 项目时,我收到以下错误: /tmp/ccG1caGi.o: In function `main': main.c:(.tex
我正在尝试从 CVS 为 Windows 上的 Emacs 23.1.50 编译 CEDET,但在“第 6 步:打开 EDE...”时出现错误:“defvar:作为变量的符号值是无效的:cedet-m
我正在(重新)学习编程,我从 C 开始。我的 IDE(如果我可以这么说)是 Windows7 上的 cygwin(32 位)和 Visual-Studio 2010。我总是编译我用 gcc (cygw
我喜欢在模板类中使用本地类来执行类似“static if”的构造。但是我遇到了 gcc 4.8 不想编译我的代码的问题。但是 4.7 可以。 这个例子: #include #include #in
我有一个项目,必须仅使用 java 1.4 进行编译。但我计划使用mockito 编写一些单元测试。我想要一种在 pom 中指定的方法,以便 src/main/java 使用 jdk 1.4 编译,但
我想了解 PHP 编译过程是如何工作的。 假设我有一个名为funcs.php 的文件并且这个文件有三个函数,如果我include 或require 它,所有的在文件加载期间编译三个函数?或者源代码会被
编译工具链 我们写程序的时候用的都是集成开发环境 (IDE: Integrated Development Environment),集成开发环境可以极大地方便我们程序员编写程序,但是配置起来
当我编写一些 Scala 代码时,在尝试编译代码时收到一条奇怪的错误消息。我将代码分解为一个更简单的代码(从语义的角度来看这完全没有意义,但仍然显示了错误)。 scala> :paste // Ent
我正在编译一个 SCSS 文件,它似乎删除了我的评论。我可以使用什么命令来保留所有评论? >SASS input.scss output.css 我在 SCSS 中看到两种类型的注释。 // Comm
这是我的代码: #include typedef struct { const char *description; float value; int age; } swag
当您编译 grails war 时,我知道 .groovy 代码被编译为字节码类文件,但我不明白容器(例如 tomcat)如何在请求 GSP 时知道如何编译它们。容器了解 GSP 吗?安装在服务器上的
我正在努力将多个文件编译成一个通用程序。我收到一个错误: undefined reference to 'pi' 这是我的代码和 Makefile 的框架。我做错了什么?谢谢! 文件:calcPi.c
我尝试使用 LD_PRELOAD 来 Hook sprintf function ,所以我将打印到缓冲区的结果: #define _GNU_SOURCE #include #include int
我正在寻找最简单的方法来自动将 CoffeeScript 重新编译为 JS。 阅读documentation但仍然很难得到我想要的东西。 我需要它来监视文件夹 src/ 中的任何 *.coffee 文
我想使用定制waveformjs 。我发现this on SO但是,我不知道如何编译/安装波形来开始。我从 GitHub 克隆它并进行了更改,但是我不知道如何将其转换为 .js 文件。 最佳答案 为了
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我是一名优秀的程序员,十分优秀!