为什么SFINAE在函数重载时报告错误

发布于 2025-01-10 18:44:54 字数 484 浏览 0 评论 0原文

以下代码无法编译,我只想测试SFINAE,为什么无法编译?

#include <type_traits>
template<typename T>
class TestVoid {
    template<std::enable_if_t<std::is_void_v<T>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<std::enable_if_t<!std::is_void_v<T>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};

int main() {
    TestVoid<void> t;
    return 0;
}

Follwing code can't compile,I just want testing SFINAE,why it can't compile?

#include <type_traits>
template<typename T>
class TestVoid {
    template<std::enable_if_t<std::is_void_v<T>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<std::enable_if_t<!std::is_void_v<T>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};

int main() {
    TestVoid<void> t;
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流云如水 2025-01-17 18:44:54

问题是 std::enable_if 的条件不依赖于 func 本身的模板参数。

您可以将代码更改为

template<typename T>
struct TestVoid {
    template<typename X = T, std::enable_if_t<std::is_void_v<X>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<typename X = T, std::enable_if_t<!std::is_void_v<X>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};

LIVE

The problem is the conditions of std::enable_if don't depend on template parameter of func themselves.

You might change the code to

template<typename T>
struct TestVoid {
    template<typename X = T, std::enable_if_t<std::is_void_v<X>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<typename X = T, std::enable_if_t<!std::is_void_v<X>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};

LIVE

紫南 2025-01-17 18:44:54

实例化类模板时,所有成员函数声明都必须有效。就你而言,其中之一不会。相反,您可以将 func 委托给另一个函数模板。

实时链接

template<typename T, std::enable_if_t<std::is_void_v<T>> * = nullptr>
void func() {
    std::cout << "void\n";
}

template<typename T, std::enable_if_t<!std::is_void_v<T>> * = nullptr>
void func() {
    std::cout << "none void\n";
}

template<typename T>
class TestVoid {
  public:
    void func_member() {
        func<T>();
    }
};

或者,如果您想将 func 的实际实现保留为成员函数:

live链接

template<typename T>
class TestVoid {
  public:
    void func_member() {
        func<T>();
    }
  private:
    template<typename U, std::enable_if_t<std::is_void_v<U>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<typename U, std::enable_if_t<!std::is_void_v<U>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};

When you instantiate the class template, all of the member function declarations must be valid. In your case, one of them won't be. Instead, you can delegate func to another function template.

live link

template<typename T, std::enable_if_t<std::is_void_v<T>> * = nullptr>
void func() {
    std::cout << "void\n";
}

template<typename T, std::enable_if_t<!std::is_void_v<T>> * = nullptr>
void func() {
    std::cout << "none void\n";
}

template<typename T>
class TestVoid {
  public:
    void func_member() {
        func<T>();
    }
};

Or, if you want to keep the actual implementation of func as a member function:

live link

template<typename T>
class TestVoid {
  public:
    void func_member() {
        func<T>();
    }
  private:
    template<typename U, std::enable_if_t<std::is_void_v<U>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<typename U, std::enable_if_t<!std::is_void_v<U>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文