c++ - 我如何使用 std::constructible_from

标签 c++ c++20 c++-concepts

我开始使用 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。
在此之后,我如何指定否定案例 *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 来诊断编译类型似乎更好...

关于c++ - 我如何使用 std::constructible_from,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63325643/

相关文章:

c++ - 使用基于概念的递归函数模板在扣除 'auto [...] ' 之前使用 'auto'

c++ - 指针运算符可以在 C++ 中重载吗?

C++ long double bigger "safe"整数

c++ - 为什么 CWnd::CreateEx 无法创建我的窗口?

c++ - 为什么 std::compare_three_way 不是模板结构/仿函数

c++ - 为什么 require 子句中的否定表达式需要括号?

c# - c++0x 概念和 c# 约束有什么区别?

c++ - 如何将 boost::hana::Sequence 的元素全部满足一个概念来表述为一个概念?

c++ - 字符串函数不会返回字符串

c++ - 如何将 C++ 概念与 type_traits 结合使用?