SFINAE 独一无二

Posted

技术标签:

【中文标题】SFINAE 独一无二【英文标题】:SFINAE make unique 【发布时间】:2017-09-08 11:18:58 【问题描述】:

有没有办法检查类型T 是否可以用可变参数模板参数包Args... 构造?我不在乎解决方案是否有效,我只想在调试模式下使用 SFINAE 或 static_assert

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)

    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));

对于其他感兴趣的人来说,这个解决方案在 C++ 11 中对我有用

template<typename T, typename... Args>
auto make_unique(Args&&... args) -> decltype(std::unique_ptr<T>(new T(std::forward<Args>(args)...)))

    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));

【问题讨论】:

尾随返回类型? auto make_unique(Args&amp;&amp;... args) -&gt; decltype(std::unique_ptr&lt;T&gt;(new T(std::forward&lt;Args&gt;(args)...)))? 如果 T 不能使用传递的参数构造,那么 new T(...) 应该会失败并给出编译器错误。您能否详细说明导致您提出这个问题的问题?也许你应该问这个? 你想做什么?通常我看到人们想要这样的模板东西,因为他们希望它完全通过一个更通用的模板(例如,如果它的随机访问迭代器这样做,如果它是双向的就这样做,否则失败)。无论如何,只有一个模板会在new 上失败? 它会失败我只是希望它是 sfinae 并给我一个指示,表明我在输入它们时没有提供正确的参数。这只是一件方便的事情。 【参考方案1】:

如果您需要一种廉价的方法来检查 T(Args...) 是否是 SFINAE 友好的有效表达式,请考虑通过 尾随返回类型使用 表达式 SFINAE

template <typename T, typename... Args>
auto foo(Args&&... args) 
    -> decltype(T(std::forward<Args>(args)...), void())



如果T(std::forward&lt;Args&gt;(args)...) 不是有效的表达式,foo 将被“SFINAEd-out”。

【讨论】:

有没有办法在 c++ 11 中做到这一点(没有自动返回) @AndreasLoanjoe 这是 c++11 :) 模板 auto make_unique(Args&&... args) -> decltype(std::unique_ptr(new T(std::forward (args)...)), void()) return std::unique_ptr(new T(std::forward(args)...)); 在 C++ 11 上为我返回 void 模板 auto make_unique(Args&&... args) -> decltype(T(std::forward(args)...), void ()) return std::unique_ptr(new T(std::forward(args)...)); 也推导出为 void @AndreasLoanjoe:当然,因为, void() 在那里 :)

以上是关于SFINAE 独一无二的主要内容,如果未能解决你的问题,请参考以下文章

使用不同的返回类型强制SFINAE

C++模板进阶指南:SFINAE

专门化模板成员函数 [SFINAE]

SFINAE 用于无符号类型选择

SFINAE模板类复杂类型的静态成员定义

具有模板化类成员函数的 SFINAE