【发布时间】:2015-04-06 09:40:30
【问题描述】:
我正在尝试使用 static_assert 来帮助我避免 C++11 中的空指针。
问题似乎是 C++11 要求编译器编译模板,即使它们没有实例化。
我有以下代码:
#include <type_traits>
template<typename T, typename... Us>
std::enable_if_t< std::is_constructible<T, Us...>::value == true, T * >
create_if_constructible(Us... args) { return new T(args...); }
template<typename T, typename... Us>
std::enable_if_t< std::is_constructible<T, Us...>::value == false, T * >
create_if_constructible(Us... args) {
static_assert( false, "Class T constructor does not match argument list.");
return nullptr;
}
struct ClassA {
ClassA(int a, string b) {}
};
void foo() {
ClassA *a = create_if_constructible<ClassA>(1, "Hello");
// ClassA *b = create_if_constructible<ClassA>(1, "Hello", "world"); // I want compile time error here.
}
我希望这个编译没有错误。但是 static_assert 已编译并给我一个编译时错误。
只有当 ClassA 的第二个实例在代码中时,它才会给我一个编译时错误。
【问题讨论】:
-
我很困惑 - 即使没有
create_if_constructible,如果您向ClassA构造函数提供错误数量的参数,您也会收到编译器错误...您在做什么导致“帮助[你] 避免使用空指针”? -
无论如何...如果您将“false”版本中的
static_assert()更改为static_assert(std::is_constructible<T, Us...>::value, "Class T constructor does not match argument list.");,它会执行您想要的操作.... -
@TonyD 我相信这仍然会违反“无法生成有效的专业化”规则,因此仍然是不正确的,不需要诊断(没有一组模板参数可以制作模板签名有效但未触发
static_assert)。解决方法很简单——template<class> class always_false : std::false_type {};和static_assert上的always_false<T>::value。但我也没有看到这段代码的意义。 -
@T.C.:你指的是 14.6/8?我不明白它为什么会适用,而且文本并没有让我清楚地知道需要有一个
static_assert不触发的条件。对我来说,应该根据签名选择模板似乎很直观,然后static_assert开始。你能分享你对相关性的理解吗?谢谢。 -
@TonyD 问题出在
enable_if与is_constructible一起考虑 - 无论is_constructible<...>的值如何,要么返回类型无效(如果为真),要么静态断言火灾(如果它是假的)。因此,您无法为其生成有效的专业化。
标签: c++ c++11 static-assert