标签: enable-if

模板特化和enable_if问题

我遇到了关于enable_if和模板特化的适当用法的问题.

修改示例后(出于保密原因),这是一个类似的例子:

我有一个名为"less"的函数,用于检查1st arg是否小于2nd arg.假设我想根据输入的类型有两种不同的实现 - 一个是整数实现,另一个是double.

到目前为止我的代码看起来像这样 -

#include <type_traits>
#include <iostream>

template <class T,
          class = typename std::enable_if<std::is_floating_point<T>::value>::type>
     bool less(T a, T b) {
  // ....
}

template <class T,
          class = typename std::enable_if<std::is_integral<T>::value>::type>
     bool less(T a, T b) {
  // ....
}

int main() {
    float a;
    float b;
    less(a,b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码没有编译,因为 - 它说我正在重新定义less方法.

错误是:

Z.cpp:15:19: error: template parameter redefines default argument
          class = typename std::enable_if<std::is_integral<T>::value>::type>

                  ^
Z.cpp:9:19: note: previous default template argument defined here …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae enable-if c++11

17
推荐指数
1
解决办法
5886
查看次数

为什么SFINAE(enable_if)不适用于类模板的成员函数?

#include <type_traits>

struct A{};
struct B{};

template <typename T>
struct Foo
{
    typename std::enable_if<std::is_same<T, A>::value>::type
    bar()
    {}

    typename std::enable_if<std::is_same<T, B>::value>::type
    bar()
    {}
};
Run Code Online (Sandbox Code Playgroud)

错误信息:

14:5: error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded 10:5: 
error: with 'typename std::enable_if<std::is_same<T, A>::value>::type Foo<T>::bar()'
Run Code Online (Sandbox Code Playgroud)

来源cpp.sh.我以为两者typename std::enable_if<std::is_same<T,?>::value>::type在同一时间都无效.

编辑

对于后人来说,这是基于@ KerrekSB答案的编辑 - SFINAE仅适用于推导出的模板参数

#include <type_traits>

struct A{};
struct B{};

template<typename T>
struct Foo
{
    template<typename U = T>
    typename std::enable_if<std::is_same<U,A>::value>::type
    bar()
    {
    }

    template<typename U = T>
    typename std::enable_if<std::is_same<U,B>::value>::type
    bar()
    {
    } …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae enable-if c++11

16
推荐指数
1
解决办法
5096
查看次数

如何使用SFINAE选择最接近的匹配类型特征?

场景:
我有多种类型可以归类为序列容器.
所有序列容器都是数据结构,但并非每个数据结构都是序列容器.

以下是代码中说明的示例.此示例中涉及的唯一"重要类型"是Array_T.它分为两类:它是一个序列容器,由于所有序列容器都是数据结构,因此它又是一个数据结构.

//A sequence container type
class Array_T{};

//A type trait for that particular sequence container
template <typename T> struct Is_Array           { static const bool value = false; };
template <>           struct Is_Array<Array_T>  { static const bool value = true;  };

//A type trait to identify all of the sequence containers
template <typename T> struct Is_A_Sequence_Container { static const bool value = Is_Array<T>::value
/* would probably "or" together more sequence types, but we only have Array_T in this …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae enable-if c++11

14
推荐指数
1
解决办法
726
查看次数

为什么函数参数类型上的enable_if会影响重载解析?

请参阅 godbolt 上的代码

#include <iostream>
#include <cmath>
#include <type_traits>

template <typename T>
void f(T, T) // 1
{
    std::cout << "Primary\n";
}

template <typename T>
void f(T, std::enable_if_t<std::is_floating_point_v<T>, T>) // 2
{
    std::cout << "Special\n";
}

/*template <typename T>
std::enable_if_t<std::is_floating_point_v<T>> f(T, T) // 3
{
    std::cout << "Special\n";
}*/

int main()
{
    f(1.1, 1.1); // prints 'Primary'
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,std::enable_if应用于第二个函数模板重载的函数类型。该函数是通过 [T = double] 推导来调用的,并且它调用重载 1。但是,如果我注释掉重载 2 并将其替换为重载 3,那么编译器会抱怨该调用不明确。我也期望在第一种情况下,为什么编译器更喜欢重载 1 而不是 2?

我阅读了“函数模板重载”部分,但对我来说,重载 2 看起来更专业。

c++ language-lawyer enable-if function-templates-overloading

14
推荐指数
0
解决办法
77
查看次数

enable_if和转换运算符?

有机会使用enable_if类型转换运算符吗?看起来很棘手,因为返回类型和参数列表都是隐式的.

c++ boost casting operator-overloading enable-if

13
推荐指数
2
解决办法
4236
查看次数

如何将std :: enable_if与自推理返回类型一起使用?

C++ 14将具有可以根据返回值推断出返回类型的函数.

auto function(){
    return "hello world";
}
Run Code Online (Sandbox Code Playgroud)

我可以将此行为应用于通过返回类型惯用法对SFINAE 使用enable_if的函数吗?

例如,让我们考虑以下两个功能:

#include <type_traits>
#include <iostream>

//This function is chosen when an integral type is passed in
template<class T >
auto function(T t) -> typename std::enable_if<std::is_integral<T>::value>::type {
    std::cout << "integral" << std::endl;
    return;
}

//This function is chosen when a floating point type is passed in
template<class T >
auto function(T t) -> typename std::enable_if<std::is_floating_point<T>::value>::type{
    std::cout << "floating" << std::endl;
    return;
}

int main(){

  function(1);    //prints "integral"
  function(3.14); …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits enable-if template-meta-programming c++14

13
推荐指数
2
解决办法
6377
查看次数

std :: enable_if如何工作?

我刚问了这个问题:std :: numeric_limits作为一个条件

我理解用于std::enable_if定义有条件地导致该方法无法编译的方法的返回类型的用法.

template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isInt(bar); }
Run Code Online (Sandbox Code Playgroud)

我不明白的是第二个参数和看似无意义的赋值,std::enable_if当它被声明为模板语句的一部分时,如Rapptz的 回答.

template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& bar) { isInt(); }
Run Code Online (Sandbox Code Playgroud)

c++ templates enable-if c++11

13
推荐指数
2
解决办法
6223
查看次数

我可以为不同的类型集定义模板吗?

我需要编写一个模板化函数,根据其参数的类别,它的行为会有所不同:

template<class ContainerType>
bool myFunc(ContainerType in){
//do some stuff
}

template<class NotAContainerType>
bool myFunc(NotAContainerType in){
//do something else
}
Run Code Online (Sandbox Code Playgroud)

我被限制在C++ 11中,所以static_if不在桌面上.此外,类的ContainerTypeNotAContainerType非常大,并且可能在将来发生变化,因此只需手动添加一些例外作为模板特化也是不明智的.

我知道std::enable_if解决方法,但是如果我需要将它应用于两个相互不同的类集,我该如何使用它?

c++ templates template-specialization enable-if c++11

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

如何使用std :: enable_if有条件地选择一个可变参数构造函数?

我试图创建一个类,它应该从其他类继承构造函数,但不从这些类本身继承.

在我的类初始化期间的某个时刻,我想使用完美转发来创建一个类型的对象,其构造函数与给定的参数匹配.

除了没有参数的默认构造函数之外,不存在歧义.

这是我的代码:

#include <string>

using namespace std;

//NOTE: this class is just an example to demonstrate the problem
class String {
    public:
        //default constructor to prevent ambiguity
        String() {}

        //construct from wstring
        template<typename... Args>
        String(enable_if<is_constructible<wstring, Args...>::value, Args>::type&&... args) : ws(forward<Args>(args)...) {}

        //construct from string
        template<typename... Args>
        String(enable_if<is_constructible<string, Args...>::value, Args>::type&&... args) : s(forward<Args>(args)...) {}
    private:
        string s;
        wstring ws;
};

void foo(const String& string) {
}

int main()
{
    foo(L"123");
    foo("123");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我尝试过很多东西,但我无法让它发挥作用.

  • 在当前的方法enable_if无法自动扣除模板args(我认为)
  • 由于我使用的构造函数我不能 …

c++ enable-if variadic-templates c++11

12
推荐指数
1
解决办法
5319
查看次数

`std :: enable_if`是函数指针 - 怎么样?

如果用户将函数指针作为参数传递,我想使用SFINAE来启用特定模板.

我用谷歌搜索但没有发现任何东西 - 我也尝试查看<type_traits>文档,但找不到任何类似的东西is_function_ptr<T>.

通过函数指针,我的意思是全局函数指针,比如TReturn(*)(TArgs...).

c++ templates pointers enable-if c++11

11
推荐指数
1
解决办法
2049
查看次数