【发布时间】:2016-07-23 01:04:24
【问题描述】:
我的问题是这个问题的延伸:How to use sfinae for selecting constructors?
在上一个问题中,提问者只想选择性地启用单个构造函数。我想根据类模板参数类型是否为默认可构造来更改构造函数的行为 - 我能想到的最好方法是让两个构造函数具有相同的用法,以便启用一个对于每个实例化。我的情况也不同,因为如果我不尝试使用enable_if 选择性地启用,则构造函数的任何一个版本都不是模板函数(而在链接的问题中,构造函数的两个版本都是在int otherN 上模板化的)。
上述问题的已接受答案中的 cmets 将我引导至 this site,这导致我创建了以下最小示例:
#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;
}
如果我注释掉第一个构造函数和 x 的声明或第二个构造函数和 y 的声明,我可以编译它(使用 -std=c++11)。我不想这样做,但是当我尝试编译器抱怨std::enable_if<false, > 中没有名为type 的类型时。
this 问题的答案对类似问题采取了另一种方法,但我不太了解起作用的因素,无法将这些方法组合成可行的方法。
【问题讨论】:
-
almost-static-if 链接需要更新。 (没有尾部斜杠)
标签: c++ templates c++11 sfinae