如何在C ++ 11中使用SFINAE从多个选项中选择构造函数 [英] How to use SFINAE to select constructor from multiple options in C++11

查看:65
本文介绍了如何在C ++ 11中使用SFINAE从多个选项中选择构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是该问题的扩展:如何使用sfinae进行选择

My question is an extension of this question: How to use sfinae for selecting constructors?

在上一个问题中,问问者只是想选择性地启用一个构造函数。我想根据类模板参数类型是否默认可构造来更改构造函数的行为-我想出的最好方法是让两个构造函数使用相同的用法,以便只启用一个对于每个实例。我的情况也有所不同,因为如果我不尝试使用 enable_if 选择性地启用,则构造函数的两个版本都不是模板函数(而在链接的问题中,构造函数在 int otherN )上进行模板化。

In the previous question, the asker just wanted to selectively enable a single constructor. I would like to change the behaviour of the constructor depending on whether the class template parameter type is default-constructible - the best way that I can come up with to do this is to have two constructors with the same usage such that exactly one is enabled for every instantiation. My case is also different because neither version of the constructor would be a template function if I weren't trying to selectively enable with enable_if (whereas in the linked question both versions of the constructor are templated on int otherN).

上面问题的可接受答案中的注释使我<一个href = https://rmf.io/cxx11/almost-static-if rel = nofollow noreferrer>此网站,这使我创建了以下最小示例:

The comments in the accepted answer to the above question led me to this site, which led me to create the following minimal example:

#include <iostream>
#include <type_traits>

namespace detail {
    enum class enabler {};
    enum class disabler {};
}

template <typename Condition>
using EnableIf = typename std::enable_if<Condition::value, detail::enabler>::type;

template <typename Condition>
using DisableIf = typename std::enable_if<!Condition::value, detail::disabler>::type;

template<typename T>
struct A {

    T data;

    // Valid if T is default-construtible; SFINAE otherwise
    template<EnableIf<std::is_default_constructible<T>>...>
    A() { std::cout << "Data defaulted" << std::endl; }


    // Valid if T is *not* default-constructible; SFINAE otherwise
    template<DisableIf<std::is_default_constructible<T>>...>
    A() : data(0) { std::cout << "Data zeroed" << std::endl; }
};

// struct which is not default-constructible
struct B {
    B() = delete;
    B(int) {}
};

int main()
{
    A<int> x; // int is default-constructible
    A<B> y; // class B is not default-constructible

    return 0;
}

我可以编译它(使用 -std = c ++ 11 )如果我注释掉第一个构造函数和x的声明或第二个构造函数和y的声明,我什么都不做,但是当我尝试编译器抱怨 std :: enable_if< false,>中没有名为 type 的类型时;

I can compile this (with -std=c++11) if I comment out the first constructor and the declaration of x or the second constructor and the declaration of y. I would like to do neither, but when I try that the compiler complains that there is no type named type in std::enable_if<false, >.

这个问题采用另一种方法来解决类似问题,但是我不了解所起作用的因素是否足以将这些方法组合成可行的方法。

The answers to this question take another approach to a similar problem, but I don't understand the factors at play well enough to be able to combine the approaches into something which works.

推荐答案

不理想,但这可以完成工作:

Not ideal, but this gets the job done:

#include <iostream>
#include <type_traits>

template<typename T>
struct A {

    T data;

    A() : A((std::is_default_constructible<T> *)nullptr) {}

private:
    A(std::true_type *) { std::cout << "Data defaulted" << std::endl; }

    A(std::false_type *) : data(0) { std::cout << "Data zeroed" << std::endl; }
};

// struct which is not default-constructible
struct B {
    B() = delete;
    B(int) {}
};

int main()
{
    A<int> x; // int is default-constructible
    A<B> y; // class B is not default-constructible

    return 0;
}

这篇关于如何在C ++ 11中使用SFINAE从多个选项中选择构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆