我一直在尝试用C ++ 11/14编写一个类型特征,告诉类型T
是否隐式默认构造。隐式/显式默认构造类型的示例:
struct Imp { Imp() = default; };
struct Exp { explicit Exp() = default; };
Imp i = {}; // ok
Exp e = {}; // error
我知道这个特性必须以某种方式用C ++ 17实现,因为std::tuple<Ts...>
的默认构造函数是显式的,当且仅当Ts...
并非所有#include <type_traits>
template<typename T>
struct IsImplicitlyDefaultConstructible {
private:
template<typename U> static void helper(const U&);
template<typename U> static std::true_type test(decltype(helper<U>({}))*);
template<typename U> static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
struct Yes { Yes() = default; };
struct No { explicit No() = default; };
int main()
{
static_assert(IsImplicitlyDefaultConstructible<Yes>::value, "");
static_assert(!IsImplicitlyDefaultConstructible<No>::value, "");
}
都是隐式可构造的。所以我想知道委员会对其可能实施的想法。
我尝试的内容如下:
{}
我们的想法是测试const T&
是否可转换为SELECT * from [dbo].[CRA]
where [gender] like 'null'
and [house] like 'null'
and [residenttime] is null
and [worktime] is null
and [loaiDN] like 'null'
and [depend] like 'null'
and [expGD] like 'null'
and [Grincome] like 'null'
and [dunocacTCTD] like 'null'
and [tinhtrangno] like 'null'
and [tgQHTD] like 'null'
and [soduTB] like 'null'
and [TlquaMB] like 'null'
。奇怪的是,上面的代码适用于GCC 6.1+,但在GCC 4/5和所有版本的Clang和CL上都失败了。请参阅演示here。
那发生了什么?这是GCC 6.1+或其他版本中的错误吗?如何使这个特性发挥作用(最好使用C ++ 11,但如果需要C ++ 14则可以)?
答案 0 :(得分:4)
您的测试用例失败的每个编译器也接受No n = {};
。
在recently之前,拥有显式默认构造函数并不会阻止类成为聚合。
聚合的 {}
执行聚合初始化,不调用任何构造函数,显式或其他。因此没有错误,因为代码没有尝试在这些编译器中调用显式构造函数。