gpt4 book ai didi

c++ - 为什么不能使用 'enable_if' 在此处禁用此声明

转载 作者:太空狗 更新时间:2023-10-29 19:51:15 25 4
gpt4 key购买 nike

#include<string>
#include<type_traits>

template<typename... Args>
class C {
public:
void foo(Args&&... args) {

}

template<typename = std::enable_if_t<(0 < sizeof...(Args))>>
void foo(const Args&... args) {

}
};

int main() {
C<> c;
c.foo();
return 0;
}

上面的代码按预期工作(由我 :))并在 msvc 2015 的运行时调用 void foo(Args&&... args) 但相同的代码失败甚至在 gcc 7.3clang 6.0.0 中编译都出现错误:

error: no type named 'type' in 'std::enable_if'; 'enable_if' cannot be used to disable this declaration

我想了解上面的代码有什么问题,如何解决?

最佳答案

SFINAE 仅适用于推导的模板参数。在您的情况下,您的方法不依赖于方法调用中的任何参数,因此它不在推导的上下文中。在实例化类本身时,一切都是已知的。

在那种情况下,MSVC 完全是错误的。

解决方法:

template<typename... Args>
class C
{
public:
template< typename U = std::tuple<Args...>>
std::enable_if_t< (std::tuple_size<U>::value > 0 ) > foo(const Args&...)
{
std::cout << "Args > 0 type " << std::endl;
}

template< typename U = std::tuple<Args...>>
std::enable_if_t< (std::tuple_size<U>::value == 0)> foo(const Args&...)
{
std::cout << "Args 0 type " << std::endl;
}
};

int main()
{
C<>{}.foo();
C<int>{}.foo(1);
}

我不知道你为什么需要这样的重载,因为如果参数列表是空的,你只需要为它写一个重载,根本不需要任何 SFINAE 的东西。

如果您的编译器没有过时(仅限 c++14),使用 constexpr if 会容易得多:

template <typename... Args>
struct C
{
void foo (const Args&... args)
{
if constexpr ( sizeof...(args) == 0)
{
std::cout << "0" << std::endl;
}
else
{
std::cout << ">0" << std::endl;
}
}
};

int main ()
{
C<> c0;
C<int> c1;
c0.foo();
c1.foo(42);
}

评论后编辑:

为了避免 SFINAE,您还可以使用像这样的专用模板类:

// provide common stuff here
template <typename ... ARGS>
class CAll { protected: void DoSomeThing(){ std::cout << "Do some thing" << std::endl; } };

template<typename ... ARGS>
class C;

// special for no args
template<>
class C<>: public CAll<>
{
public:
void foo()
{
std::cout << "none" << std::endl;
this->DoSomeThing();
}
};

//special for at minimum one arg
template<typename FIRST, typename ... REST>
class C<FIRST, REST...>: public CAll<FIRST, REST...>
{
public:
void foo( FIRST&, REST&... )
{
std::cout << "lvalue" << std::endl;
this->DoSomeThing();
}

void foo( FIRST&&, REST&&... )
{
std::cout << "rvalue" << std::endl;
this->DoSomeThing();
}
};

int main()
{
int a;
C<>{}.foo();
C<int>{}.foo(1);
C<int>{}.foo(a);
}

关于c++ - 为什么不能使用 'enable_if' 在此处禁用此声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50713692/

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