SFINAE 构造函数[重复]

问题描述 投票:0回答:2

我一直很喜欢像这样的函数 SFINAE 语法,似乎总体上工作得很好!

template <class Integer, class = typename std::enable_if<std::is_integral<Integer>::value>::type>
T(Integer n) {
    // ...
}

但是当我想在同一个班级中也这样做时,我遇到了问题......

template <class Float, class = typename std::enable_if<std::is_floating_point<Float>::value>::type>
T(Float n) {
    // ...
}

出现如下错误:

./../T.h:286:2: error: constructor cannot be redeclared
        T(Float n) {
        ^
./../T.h:281:2: note: previous definition is here
        T(Integer n) {
        ^
1 error generated.

这些构造函数不应该只针对适当的类型而存在,并且不能同时存在吗?为什么他们会冲突?

我是不是有点厚重了?

另一方面,这确实有效(但我不太喜欢语法):

template <class Integer>
T(Integer n, typename std::enable_if<std::is_integral<Integer>::value>::type* = nullptr) {
}

template <class Float>
T(Float n, typename std::enable_if<std::is_floating_point<Float>::value>::type* = nullptr) {
}
c++ sfinae enable-if
2个回答
11
投票

改用非类型模板参数:

template <class Integer,
    std::enable_if_t<std::is_integral<Integer>::value, int> = 0>
T(Integer n) {
    // ...
}

template <class Float,
    std::enable_if_t<std::is_floating_point<Float>::value, int> = 0>
T(Float n) {
    // ...
}

这是可行的,因为编译器必须先替换第一个模板参数,然后才能确定值参数的类型。


1
投票

解决此问题的一种方法是添加额外的

, typename=void
参数,以便所有重载都不会具有相同数量的模板参数。

© www.soinside.com 2019 - 2024. All rights reserved.