C++ 使用SFINAE切换构造函数时遇到问题

C++ 使用SFINAE切换构造函数时遇到问题,c++,sfinae,C++,Sfinae,我有两个构造函数,我想根据模板参数yes template <bool yes> class Base { public: template<typename std::enable_if< yes, int>::type = 0> Base() { /* yes */ } template<typename std::enable_if<!yes, int>::type = 0> Base() { /* no */

我有两个构造函数,我想根据模板参数
yes

template <bool yes>
class Base {
public:
  template<typename std::enable_if< yes, int>::type = 0>
  Base() { /* yes */ }

  template<typename std::enable_if<!yes, int>::type = 0>
  Base() { /* no */ }
};
基础上

no type named 'type' in 'std::__1::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration
在'std::uu 1::enable_if';'中没有名为'type'的类型enable_if'不能用于禁用此声明

基座上
。我所能找到的其他变体中也没有一个是有效的。如何根据
yes
选择要使用的构造函数?

这里有几个问题。首先,默认模板参数的语法是错误的,应该是:

template <bool yes>
class Base {
public:
  template<typename T=std::enable_if< yes, int>::type>
  Base() { /* yes */ }

  template<typename T=std::enable_if<!yes, int>::type>
  Base() { /* no */ }
};

构造器。两个构造函数,都有相同的签名。默认值不是签名的一部分

有几种传统的破解方法可以解决这个问题。C++库中的一种常见设计模式是声明一些辅助空类并将它们作为附加参数来消除不同方法以达到过载解决的目的。例如,用于为的等效功能选择一个特定的重载构造函数
std::optional
,或
std::in\u place\u type\u t

在您的案例中,我们可以完全自动地与委托构造函数一起使用占位符参数:

#include <iostream>

struct bool_true {};
struct bool_false {};

template<bool value> class bool_value;

template<>
struct bool_value<true> {

    typedef bool_true type;
};

template<>
struct bool_value<false> {

    typedef bool_false type;
};

template<bool v>
using bool_value_t=typename bool_value<v>::type;


template <bool yes>
class Base {
public:

    Base() : Base{ bool_value_t<yes>{} } {}

    Base(const bool_true &)
    {
        std::cout << "Yes" << std::endl;
    }

    Base(const bool_false &)
    {
        std::cout << "No" << std::endl;
    }
};

int main()
{
    Base<true> t;
    Base<false> f;
    return 0;
}
#包括
结构bool_true{};
结构bool_false{};
模板类布尔值;
模板
结构布尔值{
typedef bool_真类型;
};
模板
结构布尔值{
typedef bool_假类型;
};
模板
使用bool\u value\u t=typename bool\u value::type;
模板
阶级基础{
公众:
Base():Base{bool\u value{}}{}
基本(常数布尔_真值&)
{

如果constexpr(yes){/*…*/}else{/*…*/}在一个单一的非模板的构造函数中,它将是相同的。因为你有编译器故障,C++的目标是什么C++版本?你可能需要C++ 11,而对于<代码>如果你需要C++17i,但是它的初始化列表实际上在这些构造函数之间是不同的。g C++14,但如果有一个可行的解决方案,我可以切换到C++17。
  template<typename T>
  Base() { /* yes */ }

  template<typename T>
  Base() { /* no */ }
Base(int foo=0)
Base(int foo=1)
#include <iostream>

struct bool_true {};
struct bool_false {};

template<bool value> class bool_value;

template<>
struct bool_value<true> {

    typedef bool_true type;
};

template<>
struct bool_value<false> {

    typedef bool_false type;
};

template<bool v>
using bool_value_t=typename bool_value<v>::type;


template <bool yes>
class Base {
public:

    Base() : Base{ bool_value_t<yes>{} } {}

    Base(const bool_true &)
    {
        std::cout << "Yes" << std::endl;
    }

    Base(const bool_false &)
    {
        std::cout << "No" << std::endl;
    }
};

int main()
{
    Base<true> t;
    Base<false> f;
    return 0;
}