gpt4 book ai didi

c++ - 简单的 SFINAE 问题有条件地声明成员函数

转载 作者:行者123 更新时间:2023-12-01 14:48:06 27 4
gpt4 key购买 nike

我已阅读以下主题:

no type named ‘type’ in ‘struct std::enable_if<false, void>

Selecting a member function using different enable_if conditions

"What happened to my SFINAE" redux: conditional template class members?

但是,我似乎无法在 gcc 和 msvc 上解决这个相当简单的 SFINAE 问题:

#include <type_traits>
#include <iostream>

template<typename A, typename B>
class Test {
public:

template<typename X=A, typename = typename std::enable_if<std::is_same<X, void>::value, void>::type >
void foo() {
std::cout << "A";
}

template<typename X=A, typename = typename std::enable_if<!std::is_same<X, void>::value, void>::type >
void foo() {
std::cout << "B";
}


};

int main(int argc, char **argv) {

Test<int, float> t;

t.foo();

return 0;
}

实际结果:

A = 无效:完整错误:

main.cpp:15:8: error: 'template<class A, class B> template<class X, class> void Test<A, B>::foo()' cannot be overloaded with 'template<class A, class B> template<class X, class> void Test<A, B>::foo()'
15 | void foo() {
| ^~~
main.cpp:10:8: note: previous declaration 'template<class A, class B> template<class X, class> void Test<A, B>::foo()'
10 | void foo() {
| ^~~

A = int:完整错误:

main.cpp:15:8: error: 'template<class A, class B> template<class X, class> void Test<A, B>::foo()' cannot be overloaded with 'template<class A, class B> template<class X, class> void Test<A, B>::foo()'
15 | void foo() {
| ^~~

main.cpp:10:8: note: previous declaration 'template<class A, class B> template<class X, class> void Test<A, B>::foo()'
10 | void foo() {
| ^~~

main.cpp: In function 'int main(int, char**)':

main.cpp:26:9: error: no matching function for call to 'Test<int, float>::foo()'
26 | t.foo();
| ^

main.cpp:10:8: note: candidate: 'template<class X, class> void Test<A, B>::foo() [with X = X; <template-parameter-2-2> = <template-parameter-1-2>; A = int; B = float]'
10 | void foo() {
| ^~~

main.cpp:10:8: note: template argument deduction/substitution failed:

main.cpp:9:26: error: no type named 'type' in 'struct std::enable_if<false, void>'
9 | template<typename X=A, typename = typename std::enable_if<std::is_same<X, void>::value, void>::type >
| ^~~~~~~~

预期结果

A = void:输出“A”

A = int: 输出“B”

我想要的是基于模板参数实现一个不同的(附加的)成员函数。但是,似乎我无法使 enable_if 依赖于类模板类型,但我不确定为什么。根据链接线程,上面的代码看起来是正确的。您能否解释一下为什么这不起作用?

Live Link

最佳答案

注释来自 cppreference显示相似并解释为什么它不起作用:

A common mistake is to declare two function templates that differ only in their default template arguments. This does not work because the declarations are treated as redeclarations of the same function template (default template arguments are not accounted for in function template equivalence).

/* WRONG */

struct T {
enum { int_t,float_t } m_type;
template <typename Integer,
typename = std::enable_if_t<std::is_integral<Integer>::value>
>
T(Integer) : m_type(int_t) {}

template <typename Floating,
typename = std::enable_if_t<std::is_floating_point<Floating>::value>
>
T(Floating) : m_type(float_t) {} // error: treated as redefinition
};

/* RIGHT */

struct T {
enum { int_t,float_t } m_type;
template <typename Integer,
std::enable_if_t<std::is_integral<Integer>::value, int> = 0
>
T(Integer) : m_type(int_t) {}

template <typename Floating,
std::enable_if_t<std::is_floating_point<Floating>::value, int> = 0
>
T(Floating) : m_type(float_t) {} // OK
};

对您的代码应用相同的修复,使其输出所需的 B :

#include <type_traits>
#include <iostream>

template<typename A, typename B>
class Test {
public:

template<typename X = A,std::enable_if_t<std::is_same<X, void>::value, int> = 0>
void foo() {
std::cout << "A";
}

template<typename X=A,std::enable_if_t<!std::is_same<X, void>::value, int> = 0>
void foo() {
std::cout << "B";
}


};

在您的代码中,两个函数模板的不同之处仅在于它们的默认参数。修复后,第二个参数是 int = 0 或替换失败。

关于c++ - 简单的 SFINAE 问题有条件地声明成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61349218/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com