static_assert是否需要使用模板参数?

时间:2014-11-04 01:31:47

标签: c++ c++11

我试图禁止用我上过的课程参考,我看到一些奇怪的行为。我已经建立了一个玩具示例,显示正在发生的事情。如果我有这个:

template <class T>
struct something {
};

template <class T>
struct something<T&> {
    static_assert(false, "reference disallowed with something");
};


int main() {
    something<int>  a; (void)a;
}

即使我没有声明带引用的内容的实例,它仍然会失败:

> g++ -std=c++11 foo.cc -o foo
foo.cc:7:5: error: static assertion failed: reference disallowed with something
     static_assert(false, "reference disallowed with something");
     ^

如果我调整它以便它必须通过代理类使用模板参数,那么它可以工作:

template <class T>
struct something {
};

template <class T>
struct something<T&> {
    template <class TT> struct falsity {
        static const bool value = false;
    };
    static_assert(falsity<T>::value, "reference disallowed with something");
};

int main() {
    something<int>  a; (void)a;
}

然后它工作得很好,这是预期的行为吗?我原以为静态断言无论如何都是该类的成员。

编辑:这是gcc版本4.8.2(Ubuntu 4.8.2-19ubuntu1)

1 个答案:

答案 0 :(得分:3)

您的static_assert不依赖于任何模板参数,因此编译器不必等到类模板的实例化以评估该语句。相反,它会在two phase name lookup的第一阶段执行此操作,而您的代码无法编译。

在您的情况下,您可以通过将断言更改为

来修复失败
static_assert(!std::is_lvalue_reference<T>::value, "reference disallowed with something");