简体   繁体   English

将返回类型专门化为 void 或 const 左值引用

[英]specialize return type to void or const lvalue reference

I'm trying to accomplish the below..我正在努力完成以下..

enum class Options : uint8_t {    
    optA,
    optB,
    optC
};

class Test {
public:

    static std::string str;
    static std::vector<std::string> vec;

    template<Options option>
    static auto func()
    {
        if constexpr (option == Options::optA)
        {
            return str; // want this to deduce to 'const std::string', but only does so if 'const auto' (const std::string& also fine though)
        }
        else if constexpr (option == Options::optB)
        {
            return vec; // want this to deduce to 'const std::vector<std::string>&' but only does so if 'const auto&'
        }

        // want this to deduce to 'void' but only can if 'auto'
    }
}

But of course it doesn't work for the commented reasons.但当然,由于评论的原因,它不起作用。

I know I could...我知道我可以...

1) specialize the function outside of the class body for each option, and deliberately specify the return type 1) 为每个选项特化类体之外的函数,并特意指定返回类型

or 2) explicitly pass in the return type when calling the function或 2) 调用函数时显式传入返回类型

But is there any cleaner solution where all I need to do is pass in the single Options value into the template and the rest gets derived inside of a single function body?但是,是否有任何更简洁的解决方案,我需要做的就是将单个Options值传递到模板中,其余部分在单个函数体内派生?

const std::string& value = Test::func<Options::optA>();
const std::vector<std::string>& values = Test::func<Options::optB>();
Test::func<Options::optC>();

For a non-static func() , you can mark it as const and use decltype(auto) deduction:对于非静态func() ,您可以将其标记为const并使用decltype(auto)推导:

template<Options option>
decltype(auto) func() const
{
    if constexpr (option == Options::optA)
        return (str);
    else if constexpr (option == Options::optB)
        return (vec);
}

str and vec are parenthesized so that decltype(auto) deduce a reference type. strvec用括号括起来,以便decltype(auto)推导出引用类型。 For optA it will return const std::string& , for optBconst std::vector<std::string>& , and void otherwise.对于optA ,它将返回const std::string& ,对于optBconst std::vector<std::string>& ,否则返回void

Demo 1演示 1


For a static member function and static members you can write:对于静态成员函数和静态成员,您可以编写:

template<Options option>
static decltype(auto) func()
{
    if constexpr (option == Options::optA)
        return std::as_const(str);
    else if constexpr (option == Options::optB)
        return std::as_const(vec);
}

Demo 2演示 2

There is no need to return a const std::string .无需返回const std::string You can just return a std::string and the caller can decide if it wants it to be const or not.你可以只返回一个std::string ,调用者可以决定它是否希望它是 const 。 If you are okay with that, then your function would become如果你同意这一点,那么你的函数就会变成

template<Options option>
static decltype(auto) func()
{
    if constexpr (option == Options::optA)
    {
        return str;
    }
    else if constexpr (option == Options::optB)
    {
        return const_cast<const std::vector<std::string>&>(vec);
    }
    else        //
    {           // this bit is not really needed but I like 
        return; // being explicit that `void` is what we want to return
                //
    }           //
}

and now decltype(auto) will deduce for Options::optA a std::string , for Options::optB a const std::vector<std::string>& and for Options::optC , void .现在decltype(auto)将为Options::optA推导出std::string ,对于Options::optBconst std::vector<std::string>&和对于Options::optCvoid

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM