static_assert 取决于 class 模板

static_assert depend on class template

考虑以下代码:

template <unsigned int N>
struct myclass
{
    unsigned int f() {return N;}
    unsigned int g() {static_assert(N > 0, ""); return N-1;}
};

问题: 我能保证下面的代码能编译吗:

myclass<0> c;
c.f();

但以下不会:

myclass<0> c;
c.f();
c.g();

是的,你有那个保证。来自 [temp.inst]/11,强调我的:

An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation.

如果不调用g(),不需要实例化,所以调用myclass<0>{}.f().

应该没有问题

这与允许您将 std::vectorstd::map 与不可默认构造的类型一起使用的保证相同,只要您不执行调用 resize()operator[],分别。

作为 Jarod42 的后续行动是显式实例化 myclass<0> 将产生断言,因为来自 [temp.explicit]/8:

An explicit instantiation that names a class template specialization is also an explicit instantiation of the same kind (declaration or definition) of each of its members (not including members inherited from base classes and members that are templates) that has not been previously explicitly specialized in the translation unit containing the explicit instantiation, except as described below.

例外情况不适用于此处。

如果你想在编译时禁用一个函数,你应该使用 enable_if 而不是 static_assert

template<unsigned int N>
struct Foo {
    unsigned int f() {}
    enable_if_t<(N > 0), unsigned int> g() {}
};

Foo<0> t{};
t.f(); /// this is okay and will compile
// t.g() if I uncomment this line, it will not compile anymore.

使用模板专业化:

template <unsigned N>
struct myclass
{
    unsigned f () { return N; }
    unsigned g () { return N-1; }
};

template <>
struct myclass <0>
{
    unsigned f () { return 0; }
};