相关疑难解决方法(0)

SFINAE工作在返回类型但不作为模板参数

我已经使用了SFINAE习惯用了很多次,我习惯于把std::enable_if<>模板参数放在模板参数而不是返回类型中.但是,我遇到了一些不起作用的琐碎案例,我不知道为什么.首先,这是我的主要内容:

int main()
{
    foo(5);
    foo(3.4);
}
Run Code Online (Sandbox Code Playgroud)

这是一个foo触发错误的实现:

template<typename T,
         typename = typename std::enable_if<std::is_integral<T>::value>::type>
auto foo(T)
    -> void
{
    std::cout << "I'm an integer!\n";
}

template<typename T,
         typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
auto foo(T)
    -> void
{
    std::cout << "I'm a floating point number!\n";
}
Run Code Online (Sandbox Code Playgroud)

这是一个可以正常工作的等效代码:

template<typename T>
auto foo(T)
    -> typename std::enable_if<std::is_integral<T>::value>::type
{
    std::cout << "I'm an integrer!\n";
}

template<typename T>
auto foo(T)
    -> typename std::enable_if<std::is_floating_point<T>::value>::type
{
    std::cout << "I'm a floating point number!\n";
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么第一次执行 …

c++ templates sfinae c++11

33
推荐指数
3
解决办法
5073
查看次数

为什么模板参数中的enable_if_t会抱怨重定义?

我有以下案例可以使用std::enable_if:

template<typename T,
         typename std::enable_if<std::is_same<int, T>::value>::type* = nullptr>
void f() { }

template<typename T,
         typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr>
void f() { }
Run Code Online (Sandbox Code Playgroud)

现在,我在cppreference中看到了新的语法,在我看来更加清晰: typename = std::enable_if_t<std::is_same<int, T>::value>>

我想移植我的代码:

template<typename T,
         typename = std::enable_if_t<std::is_same<int, T>::value>>
void g() { }

template<typename T,
         typename = std::enable_if_t<std::is_same<double, T>::value>>
void g() { }
Run Code Online (Sandbox Code Playgroud)

但现在海湾合作委员会(5.2)抱怨:

error: redefinition of 'template<class T, class> void g()'
       void g() { }
Run Code Online (Sandbox Code Playgroud)

为什么会这样 ?如果可能,我该怎么做才能在这种情况下使用新的,更简洁的语法?

c++ templates sfinae enable-if c++14

29
推荐指数
2
解决办法
2万
查看次数

使用SFINAE启用转换运算符

我正在尝试operator T()使用SFINAE 重载以在T基本类型时返回副本,并在T类时使用const引用.

double下面的示例中使用a 时,我无法std::is_class删除第二个重载(with ).

也就是说,我得到的错误是:

error: no type named ‘type’ in ‘struct std::enable_if<false, const double&>’
operator typename std::enable_if< std::is_class<T>::value, const T&>::type () const
^
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

#include <iostream>
#include <type_traits>

template<typename T>
struct Foo
{
    operator typename std::enable_if<!std::is_class<T>::value, T >::type () const
    {
        return _val;
    }

    operator typename std::enable_if< std::is_class<T>::value, const T&>::type () const
    {
        return _val;
    }

    T _val;
};

int main()
{
    Foo<double> f1;
    f1._val = 0.3; …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae type-traits enable-if

9
推荐指数
2
解决办法
1530
查看次数

SFINAE构造师

我一直喜欢这样的SFINAE语法功能,似乎一般都运行良好!

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

但是当我想在同一个班级做同样的事情时,我遇到了一个问题......

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

得到如下错误:

./../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.
Run Code Online (Sandbox Code Playgroud)

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

我在这里有点厚吗?

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

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) {
}
Run Code Online (Sandbox Code Playgroud)

c++ sfinae

4
推荐指数
1
解决办法
287
查看次数

标签 统计

c++ ×4

sfinae ×4

templates ×3

enable-if ×2

c++11 ×1

c++14 ×1

type-traits ×1