相关疑难解决方法(0)

在 C++ 中函数 SFINAE 的方法

我在一个项目中大量使用 SFINAE 函数,但不确定以下两种方法(样式除外)之间是否存在任何差异:

#include <cstdlib>
#include <type_traits>
#include <iostream>

template <class T, class = std::enable_if_t<std::is_same_v<T, int>>>
void foo()
{
    std::cout << "method 1" << std::endl;
}

template <class T, std::enable_if_t<std::is_same_v<T, double>>* = 0>
void foo()
{
    std::cout << "method 2" << std::endl;
}

int main()
{
    foo<int>();
    foo<double>();

    std::cout << "Done...";
    std::getchar();

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

程序输出如预期:

method 1
method 2
Done...
Run Code Online (Sandbox Code Playgroud)

我已经看到方法 2 在 stackoverflow 中使用得更频繁,但我更喜欢方法 1。

这两种方法有什么不同吗?

c++ sfinae

45
推荐指数
2
解决办法
1889
查看次数

SFINAE在类型和非类型模板参数的情况下工作方式不同

为什么这段代码有效:

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

template<
    typename T, 
    std::enable_if_t<!std::is_same<T, int>::value, T>* = nullptr>
void Add(T) {}
Run Code Online (Sandbox Code Playgroud)

并且可以正确区分这两个调用:

Add(1);
Add(1.0);
Run Code Online (Sandbox Code Playgroud)

而以下代码如果编译导致重新定义Add()错误?

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

template<
    typename T, 
    typename = typename std::enable_if<!std::is_same<T, int>::value, T>::type>
void Add(T) {}
Run Code Online (Sandbox Code Playgroud)

所以如果模板参数是类型,那么我们就重新定义了函数,如果它是非类型的,那么一切都好.

c++ templates overloading sfinae c++11

20
推荐指数
2
解决办法
1194
查看次数

了解SFINAE

据我所知,SFINAE意味着替换失败不会导致编译错误,只是从可能的重载列表中删除原型.

我不明白:为什么这个SFINAE:

template <bool C, typename T = void> struct enable_if{};
template <typename T> struct enable_if<true, T> { typedef T type; };
Run Code Online (Sandbox Code Playgroud)

但这不是吗?

template <bool C> struct assert;
template <> struct assert<true>{};
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这里的基本逻辑是相同的.这个问题来自对这个答案的评论.

c++ templates sfinae c++11 argument-deduction

13
推荐指数
1
解决办法
2770
查看次数

使用std :: enable_if作为templ时的默认模板参数.param.:为什么两个模板函数只在enable_if参数中有所不同?

cppreference语言参考中std::enable_if包括以下注释

笔记

一个常见的错误是声明两个仅在默认模板参数上有所不同的函数模板.这是非法的,因为默认模板参数不是函数模板签名的一部分,并且声明具有相同签名的两个不同函数模板是非法的.

在下面的示例中的模板函数中,在我看来,这种情况发生.即,两个模板函数onlyForDerivedObjects(...)似乎(对我来说)仅由它们的默认模板参数不同.我意识到我在这里遗漏了一些东西,希望有人可以向我解释这一点,或者指出我可能会为自己找到顿悟的方向.

  • 问题:上面的引用,为什么下面的例子编译并运行正常:typename std::enable_if ...当我认为它产生两个模板函数的情况时,我在下面的模板函数中错误分类了部分,这两个模板函数的区别仅在于它们的默认模板参数?

基础和派生类:

class BaseA
{
public:
  int getInt() const { return 21; };
};

class DerivedA : public BaseA {};

class BaseB
{
public:
  int getAnotherInt() const { return 33; };
};

class DerivedB : public BaseB {};
Run Code Online (Sandbox Code Playgroud)

具有以下模板功能

/* template functions that, seemingly, only differ in their
   default template arguments? */
template< class T,
          typename std::enable_if<std::is_base_of<BaseA, …
Run Code Online (Sandbox Code Playgroud)

c++ templates enable-if c++11

11
推荐指数
2
解决办法
959
查看次数