3

我有一些情况,有时bool我想调用 2 个constexpr返回不同类型的函数并将其分配给auto常量。

不幸的是,三元运算符需要类型“相似”。

我在下面的代码中有解决方法,但它非常冗长。有没有更好的办法?

#include <iostream>
#include <string>

constexpr int get_int(){
    return 47;
}

constexpr std::string_view get_string(){
    return "47";
}

constexpr bool use_str = false;

constexpr auto get_dispatch(){
    if constexpr(use_str){
        return get_string();
    } else{
        return get_int();
    }

}
int main()
{
    // what I want : constexpr auto val =  use_str ? get_string():get_int();
    // what works:
    constexpr auto val = get_dispatch();
    std::cout << val << std::endl;
}
4

4 回答 4

3

另一种选择是使用标签调度:

constexpr int get(std::false_type) {
    return 47;
}

constexpr std::string_view get(std::true_type) {
    return "47";
}

int main() {
    constexpr auto val = get(std::bool_constant<use_str>{});
    std::cout << val << std::endl;
}
于 2018-10-10T22:36:25.753 回答
2

不确定它是否更好,但有std::variant

int main()
{
    using my_variant = std::variant<int, std::string_view>;
    constexpr auto val =  use_str ? my_variant{get_string()} : my_variant{get_int()};
    std::visit([](const auto& v) {std::cout << v << std::endl;}, val);
}

演示

于 2018-10-10T22:52:24.150 回答
1

这应该工作:

template <bool>
struct value_chooser;

template<>
struct value_chooser<true>
{
    static constexpr auto value = "47";
};

template<>
struct value_chooser<false>
{
    static constexpr auto value = 47;
};

int main()
{
    auto value1 = value_chooser<true>::value;
    auto value2 = value_chooser<false>::value;
}

活生生的例子

于 2018-10-10T22:33:08.400 回答
1

我在下面的代码中有解决方法,但它非常冗长。有没有更好的办法?

使用 C++17,您可以使用if constexpr,在我看来这是一个很好的解决方案。

如果您真的想要一些不同的东西,我提出了一种基于模板功能完全专业化的方法(Evg 和 Slava 解决方案的混合)

我的意思是

#include <iostream>
#include <string>

template <bool>
constexpr auto get_value ()
 { return 47; }

template <>
constexpr auto get_value<true> ()
 { return std::string_view{"47"}; }

int main()
 {
    constexpr auto use_str = false;
    constexpr auto val     = get_value<use_str>();

    std::cout << val << std::endl;
}

正如 Slava 所指出的,具有默认版本和针对一种情况的显式特化的模板函数的可读性可能会降低。

所以,如果你更喜欢一个更冗长但更易读的变体,你可以写两个明确的特化get_value()如下

template <bool>
constexpr auto get_value ();

template <>
constexpr auto get_value<false> ()
 { return 47; }

template <>
constexpr auto get_value<true> ()
 { return std::string_view{"47"}; }
于 2018-10-11T12:28:38.293 回答