如何使用 std::constructible_from

How do I use std::constructible_from

我刚开始学习 C++ 概念,但在使用时遇到了问题。

例如这里我想做一个乐观的create_unique函数

template<typename Arg, constructible_from<Arg> CreatedClass >       *1
unique_ptr<CreatedClass>
create_unique( Arg && arg ) {
    return make_unique<CreatedClass>( forward<Arg>( arg ) );
}
template<typename CreatedClass, typename Arg, 
         enable_if_t< !is_constructible<CreatedClass, Arg>::value, int > = 0>   *2
unique_ptr<CreatedClass>
create_unique( Arg && arg ) {
    throw runtime_error( "CreatedClass is not constructible from arg." );
}

int main() {
    auto x = create_unique2<string>("Hello"s);    *3
    // auto x = create_unique2<string>(42);
}

这不会编译,因为在 *1 中,CreatedClass 位于 Arg 之后。因此,为了编译它,我必须明确指定两个模板参数。

    auto x = create_unique2<string, string>("Hello"s);

如果我写

template<constructible_from<string> CreatedClass, typename Arg >       *1
unique_ptr<CreatedClass>
create_unique( Arg && arg ) {
    return make_unique<CreatedClass>( forward<Arg>( arg ) );
}

然后 *3 编译,但现在 CreatedClass 不再依赖于 Arg。

在此之后,如何指定 negative case *2?使用老式 enable_if.

似乎有点 不干净

就这样:

template <typename CreatedClass, typename Arg>
    requires std::constructible_from<CreatedClass, Arg>
auto create_unique(Arg&&) -> std::unique_ptr<CreatedClass>

没有使用更简洁的约束语法 - requires 始终可用。

否定的情况将是没有约束的重载:

template <typename CreatedClass, typename Arg>
auto create_unique(Arg&&) -> std::unique_ptr<CreatedClass>

首选更受约束的情况。但这是非常值得怀疑的,为什么要将此错误推迟到运行时?似乎通过没有 create_unique...

的可行重载来更好地诊断编译类型