首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可选成员的Decltype

可选成员的Decltype
EN

Stack Overflow用户
提问于 2019-02-06 17:26:23
回答 2查看 384关注 0票数 3

我正在尝试从结构成员中获取类型,该类型位于一个std::optional<>中,它是一个成员函数的返回类型。

这是一个简化的示例:

代码语言:javascript
复制
struct Result
{
    int tag;
    int pos;
};

class Dict
{
public:
    std::optional<Result> search(const char *word)
    {
        return Result{ 1,2 };
    }
};

我希望能够做这样的事情:

代码语言:javascript
复制
int main()
{
    Dict abc;
    decltype(abc.search(const char*)->pos) position;

    return 0;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-06 17:31:51

如果您将一个实际参数传递给search,它将工作(同时将search设置为公共):

https://wandbox.org/permlink/0Q3mLW7SmQW4QshE

代码语言:javascript
复制
#include <optional>

struct Result
{
    int tag;
    int pos;
};

class Dict
{
public:
    std::optional<Result> search(const char *word)
    {
        return Result{ 1,2 };
    }
};

int main()
{
    Dict abc;
    decltype(abc.search("")->pos) position;

    return 0;
}

search的参数不一定是有效的(就您的函数所期望的而言-因为它实际上不会调用它),它只需要是正确的类型。

如果您想要直接处理类型,而不是您的注释所建议的实例,那么@Jarod42指出您可以使用以下行来声明变量:

decltype(std::declval<Dict>().search(std::declval<const char*>())->pos) position;

https://wandbox.org/permlink/kZlqKUFoIWv1m3M3

虽然我可能不需要指出一个大约70个字符的变量类型是多么的不可读。我想如果是我,我会使用int,或者我会为pos创建一个类型别名,例如using ResultPositionType = int;,然后在Result结构中使用它,然后在main中再次使用。

票数 6
EN

Stack Overflow用户

发布于 2019-02-06 22:43:45

Mark给出了你问题的直接答案。

但是,我提出了一个更易于阅读的解决方案,它借用了标准库对类型别名的严重依赖。它们基本上是免费的,尽管在类定义中有一点嘈杂:

代码语言:javascript
复制
#include <optional>

struct Result
{
    using TagType = int;
    using PosType = int;

    TagType tag;
    PosType pos;
};

class Dict
{
public:
    using ResultType = Result;

    std::optional<ResultType> search(const char* word)
    {
        return ResultType{ 1, 2 };
    }
};

int main()
{
    Dict abc;
    Dict::ResultType::PosType position;
}

这具有自文档化的优点,并且不需要只有C++标准语言使用者才能理解的70个字符的语句。:)

它在类定义本身中也有价值,因为现在您有了一个地方来设置这些类型,并且在语义允许的情况下,可以比过去更容易地更改它们(当您必须修改每个成员函数、每个数据成员…时)。。

一个缺点是,两个Result成员的内在性并不是很明显。这是否是一个问题取决于您的实际代码,特别是Result的实际大小以及它的常用用法。作为一种折衷方案,您可以考虑删除该级别的类型别名,只保留Dict::ResultType,然后使用decltype(declval<Dict::ResultType>().pos)深入研究它。只有你才能决定这种方法要走多远。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54550253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档