Skip to content

Clang 和 GCC 下 对构造函数使用SFINAE 的问题 #18

Answered by frederick-vs-ja
AzrBrk asked this question in Q&A
Discussion options

You must be logged in to vote

首先问题描述本身存在一些错误:复制构造函数与移动构造函数都不能是函数模板
所以样例代码中涉及的构造函数都不是复制或移动构造函数。而且复制构造函数和移动构造函数仍然会被隐式声明(假设模板头被改正),从而题主引入的函数模板不会得到选择。

如果要对复制或移动特殊成员函数使用 SFINAE,可以这么做:

  • 使用 C++20 requires,或
  • 引入对应的特殊成员函数条件性 = delete;= default;基类非静态数据成员,标准库中 std::optionalstd::variant 的实现就使用各种专门定制的基类(因为需要用 C++17 语核实现)。

我们可以记住一条规则:参与传统 SFINAE 的模板形参一定要是在当前模板中引入的
外围的模板形参不再参与推导或替换,从而会导致硬错误。


不过,如果题主的意图不是“使用复制或移动构造函数”,而是“使用函数模板,但使之能用于复制或移动构造”的话,可以这么做。(Godbolt link

#include <type_traits>
#include <utility>

template<class T>
class A{
private:
    T a{};

    A(const volatile A&) = delete; // This is a copy ctor!

public:
    A() = default;

    template<class U = T, class = std::enable_if_t<std::is_same_v<U, int>>>
    A(c…

Replies: 4 comments 10 replies

Comment options

You must be logged in to vote
1 reply
@AzrBrk
Comment options

Comment options

You must be logged in to vote
7 replies
@AzrBrk
Comment options

@Mq-b
Comment options

@Mq-b
Comment options

@Mq-b
Comment options

@frederick-vs-ja
Comment options

Comment options

You must be logged in to vote
0 replies
Comment options

You must be logged in to vote
2 replies
@Mq-b
Comment options

@Mq-b
Comment options

Answer selected by Mq-b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
bug 代码错误或解释不准确 review 还需要审阅 issue-luse 此 issue 有一定作用 issue-resolved 问题已解决
4 participants