12

考虑这个代码片段,

template<bool b>
struct other
{
    static const bool value = !b;
};

template<bool b>
struct test
{
    static const bool value = b || other<b>::value;
};

int main()
{
      bool value = test<true>::value;   
}

other<true>当实例化似乎完全没有必要时,编译器是否会在上述情况下实例化?或者仅仅因为我已经编写了语法,编译器必须实例化它,而不管它对?other<b>::value的值的计算完全没有贡献。test<true>::value

我想听听,a)标准要求什么,以及 b)各种编译器实际实现了什么?标准中的相关部分将不胜感激。

4

2 回答 2

9

根据 C++ 规范,$14.7.1/4 部分:

“如果在需要完全定义的对象类型的上下文中使用类类型,或者如果类类型的完整性影响程序的语义,则类模板特化被隐式实例化;特别是,如果类型为类模板特化涉及重载决议”

在您使用短路说明的情况下,该类必须具有完整的类型,因为您正在查看它的内部以找到 value 静态成员。这阻止了编译器使表达式短路。

至于实践中实际发生的情况,我不确定,因为我看不出编译器如何不进行实例化而侥幸逃脱。例如,假设 的实例化other<b>如下所示:

template <bool B> struct other {
    typedef int value;
};

在这里,您的程序将是格式错误的,因为other<b>::value 是一个类型,而不是一个值,但是编译器无法在没有实际执行实例化的情况下诊断错误。

于 2011-01-05T04:07:51.617 回答
0

注意,由于constexpr在C++11中引入了函数,可以实现短路:

template<bool b>
constexpr bool test_other();

template<bool b>
struct test
{
    static const bool value = b || test_other<b>();
};

int main()
{
    bool value = test<true>::value;
}

...虽然test_other()未定义,但编译器不会尝试调用它。

不幸的是,这不适用于consteval. 在这种情况下,第一级“测试设施”test本身必须是一个函数:

template<bool b>
consteval bool test_other();

template<bool b>
consteval bool test()
{
    return b || test_other<b>();
};

int main()
{
    bool value = test<true>();
}
于 2021-11-25T22:03:42.263 回答