C++编译时函数执行

2023-11-25

我的代码中有字符串标签,它们被转换为数字并用于搜索标签值结构中的值。

我有这样的事情:

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),但我不确切知道如何迭代以空结尾的字符串并将中间值保留在模板中。您能否给出一个简单的示例,该示例迭代一个以 null 结尾的字符串并将字符添加到公共变量中?


听起来你想要的是Boost.MPL's boost::mpl::string。编写一个元函数来转换一个或多或少是微不足道的mpl::string在编译时使用整型mpl::fold(或者如果字符串文字不代表有效的整数值,则编译失败)。

EDIT:

我不完全确定您在寻找什么,因此根据解释,这里实际上有两个不同的答案:


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您正在寻找的是编译时字符串到整数值mapping(例如,所以"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) 可以将积分值作为模板参数而不是作为函数参数,如果这样做对其实现有意义的话。

希望这能回答您的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++编译时函数执行 的相关文章

  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

  • 使用 $ORIGIN 指定 ELF 二进制文件中的解释器不起作用

    我在用着patchelf修改 rpath 和已编译二进制文件的解释器 对 patchelf 的调用如下所示 patchelf set interpreter ORIGIN lib ld linux x86 64 so 2 set rpath
  • 转储 ChartJS 数据中缺失的日期

    假设我将使用 ChartJS 中的折线图 并且我有 按日期计算的值 数据 例子 5 05 11 2014 10 04 11 2014 55 01 11 2014 该图表将包含 3 个点 有没有任何解决方案 配置可以让我自动添加 转储 缺失日
  • 编写 repr 方法

    情况 我是Python新手 目前正在尝试学习诀窍 我尝试创建一个链表类来帮助更好地理解该语言及其结构 我知道 repr 函数基本上应该返回相同的东西 str 但我不确定实际的区别是什么 到目前为止 这是我的课程 class LinkedLi
  • 如何声明多个变量?

    这是字母 letters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 我用这个列出了它的清单 chars for i in letters chars app
  • 将文本安全转换为 XML

    我的 SQL Server 2005 数据库中有超过一百万行 其中一个文本列包含 XML 字符串 我想将文本转换为 XML 数据类型 以便提取部分数据 问题是有些记录在转换时会抛出错误 即无效的 XML 如何忽略这些错误 以便正确转换所有有
  • 检索 Groovy 闭包/方法参数列表

    我们如何通过参数数组以 javascript 风格动态检索 groovy 中闭包 方法的参数列表 举例来说 我想以这种方式记录一条消息 def closure name id gt log debug Executing method wi
  • 如何删除所有控件的全局 FocusVisualStyle?

    我遇到了同样的问题全局停用 FocusVisualStyle 但所有答案都不起作用 所以 我只想设置我的应用程序中的所有控件FocusVisualStyle x Null 任何 实现这一目标的有效方法是什么 我不想单独设置每个控件 将其放入
  • 网络聊天应用程序 - ASP.NET/Jabber/Ajax/WCF/Comet/ReverseAjax - 面临的问题 - 寻求见解

    在过去的三周里 我一直在尝试构建一个基于网络的聊天应用程序 但我在构建它时遇到了任何路线 编程技术 技术 的问题 我在下面解释了我遇到的所有问题 请提供您对此的任何见解 ASP NET AJAX 第一个问题是不是真正的实时 如果客户端每 x
  • 跨域网址

    我试图在我的 javascript 代码中调用这个 URL 这是我的 JavaScript 代码 ajax url http api addressify com au address autoComplete type GET cross
  • ES6 类的 jest.mock 产生 ReferenceError: require is not Defined

    我正在尝试在我的 ES6 javascript 项目中使用 jest 创建一个自动模拟 我正在使用节点v15 0 1 还有开玩笑26 6 0在Ubuntu上18 04 5 我有一个包含以下代码的测试文件 import RenderBuffe
  • 在 WPF 中未指定控件名称...性能影响

    如果需要从后面的代码访问 WPF 控件 则需要提供Name在 XAML 中为其添加属性 在许多情况下 您不需要从后面的代码访问控件 因为许多编码逻辑 例如绑定 最好直接在 XAML 中应用 我的问题是 是否有性能提升not向控件提供名称属性
  • SQL Server 临时表在 pyodbc 代码中不可用

    我正在 python 中运行一系列复杂的 sql 查询 它涉及临时表 我的自动提交方法似乎无法从临时表中检索数据 我在下面使用的代码片段是我得到的输出 testQuery Select top 10 INTO Temp1 FROM Tabl
  • Webpack 开发服务器抛出错误 - 拒绝执行脚本,因为其 MIME 类型('text/html')不可执行

    我使用 Webpack 捆绑器和 Webpack 开发服务器进行本地开发 前端采用React js Redux 后端采用Node js和koajs 在后端 我使用护照用于用户身份验证的库和其他库koa 护照 护照脸书 护照谷歌身份验证通过
  • 如何从二维数组中删除一行?

    我有一个简单的数组 有点像这样 1 2 3 4 5 6 7 8 9 6 2 7 2 9 6 8 10 5 2 6 4 7 8 4 3 2 5 9 8 7 5 9 7 4 1 10 5 3 6 8 2 7 3 7 2 所以 我们称之为matr
  • 在 SQLAlchemy 中从集合中删除对象

    我将大量专利数据存储在 MySQL 数据库中 并通过 SQLAlchemy 与其进行交互 我在专利类中有一个集合 代表受让人列表 被分配专利的公司 assignees relationship Company secondary paten
  • 如何使用 Visual Studio Code 在 dotnet 构建中包含资源文件

    我正在 Visual Studio 代码编辑器中使用 dotnet core 构建 WPF 应用程序 我遇到的问题是资源文件夹不包含在构建中 或者看起来是这样 我找不到如何在 Visual Studio 之外执行此操作的示例 并且我尝试使用
  • 如何从Spark RDD中的特定分区获取数据?

    我想访问 Spark RDD 中特定分区的数据 我可以按如下方式获取分区的地址 myRDD partitions 0 但我想从中获取数据myRDD partitions 0 分割 我尝试了官方 org apache spark 文档但找不到
  • Ubuntu 13.04:如何构建Monodevelop 4.0.1?

    我从git下载了源码 git clone git github com mono monodevelop git 和依赖项 cd monodevelop git submodule init git submodule update 我设置
  • 如何在 Bash 中解析 XML?

    理想情况下 我希望能够做的是 cat xhtmlfile xhtml getElementViaXPath path html head title sed e s g gt titleOfXHTMLPage txt 这实际上只是一个解释Y
  • C++编译时函数执行

    我的代码中有字符串标签 它们被转换为数字并用于搜索标签值结构中的值 我有这样的事情 void foo type value search SomeTag 其中搜索定义如下 type search const char tag return