[英]Failing to compile explicitly specialized template struct on g++/clang++ with std::enable_if
I've tried to compile this with msvc and it compiles fine.我试图用 msvc 编译它,它编译得很好。 On the other hand I failed to compile it with g++ and clang++.另一方面,我未能用 g++ 和 clang++ 编译它。 Error I get is no type named 'type' in 'struct std::enable_if<false, void>'
.我得到的错误是no type named 'type' in 'struct std::enable_if<false, void>'
。 How would I resolve this error?我将如何解决此错误?
#include <type_traits>
template <bool v>
struct a {
template <typename T = typename std::enable_if<v>::type>
void function();
};
template struct a<false>;
template struct a<true>;
template<bool v>
template<typename T>
void a<v>::function() { }
int main() {
}
I'm trying to make void function
visible if passed bool
template is true
.如果传递的bool
模板为true
,我正在尝试使void function
可见。
You are not using SFINAE correctly because the bool
you pass to enable_if
(which is v
) is not dependent on the function template parameters.您没有正确使用 SFINAE,因为您传递给enable_if
的bool
(即v
)不依赖于 function 模板参数。
The canonical way to selectively add or remove members of a class template is to use template specialization.选择性地添加或删除 class 模板成员的规范方法是使用模板特化。 For example:例如:
template <bool v>
struct a {
void function();
};
template< >
struct a<false> {
};
Now, only a<true>
will have the function
member.现在,只有a<true>
将具有function
成员。 If you have many common members that should be present in a
regardless of v
, you can move these members to a base class and derive both specializations from it:如果您有许多公共成员应该存在于a
而与v
无关,您可以将这些成员移动到基础 class 并从中派生两个专业化:
struct a_common {
void common_function();
};
template <bool v>
struct a : public a_common {
void function();
};
template< >
struct a<false> : public a_common {
};
This can be achieved with SFINAE as well, but it will require a bit of a trick.这也可以通过 SFINAE 实现,但需要一些技巧。 As mentioned above, we need to make function
a template, and we need to ensure that the condition used in enable_if
depends on its template parameters.如上所述,我们需要将function
一个模板,并且我们需要确保enable_if
中使用的条件依赖于它的模板参数。 Since we don't have any template parameters, we need to add a dummy one:由于我们没有任何模板参数,我们需要添加一个虚拟参数:
template <bool v>
struct a {
template<
typename Dummy = void,
typename = typename std::enable_if<
std::is_same< Dummy, Dummy >::value && v
>::type
>
void function();
};
Here, we use is_same
trait to introduce a formal dependency on the Dummy
template parameter when calculating the first template parameter of enable_if
.在这里,我们使用is_same
trait 在计算enable_if
的第一个模板参数时引入对Dummy
模板参数的正式依赖。 Naturally, the result of is_same
will be true
, so effectively v
decides whether the function
template can be instantiated.自然地, is_same
的结果将为true
,因此v
有效地决定了function
模板是否可以被实例化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.