实例化模板时短路?

发布于 2024-10-10 06:05:00 字数 538 浏览 6 评论 0原文

考虑这个代码片段,

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 ?或者仅仅因为我编写了语法 other::value,编译器就必须实例化它,无论它对 test值的计算完全没有贡献;::值

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

Consider this code snippet,

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;   
}

Do compilers instantiate other<true> in situations such as the above, when instantiating seems completely unnecessary? Or just because I've written the syntax other<b>::value, compilers must instantiate it regardless of the fact that it contributes absolutely nothing to the calculation of the value of test<true>::value?

I would like to hear, a) what is required by the Standard, and b) what is actually implemented by the various compilers? Relevant sections from the Standard would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海夜未眠 2024-10-17 06:05:00

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

“类模板特化是
隐式实例化,如果该类
类型用于以下上下文中
需要一个完全定义的对象
输入或者如果完整性
类类型影响语义
该计划
;特别是,如果
类型为类的表达式
模板专业化涉及
重载解析”

的情况下,该类必须具有完整的类型,因为您要在其内部查找值静态成员。这会阻止编译器短路表达式

。对于实践中实际发生的情况,我不确定,因为我看不出编译器如何能够不进行实例化,例如,假设 other 的实例化看起来是这样。像这样:

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

在这里,您的程序格式不正确,因为 other::value 是一种类型,而不是值,但编译器在不实际进行实例化的情况下无法诊断错误。

According to the C++ spec, section $14.7.1/4:

"A class template specialization is
implicitly instantiated if the class
type is used in a context that
requires a completely-defined object
type or if the completeness of the
class type affects the semantics of
the program
; in particular, if an
expression whose type is a class
template specialization is involved in
overload resolution"

In the case you illustrated with short-circuiting, the class would have to have a complete type, because you're looking inside of it to find the value static member. This precludes the compiler from short-circuiting the expression.

As for what actually happens in practice, I'm not sure because I can't see how the compiler could get away with not doing the instantiation. For example, suppose that the instantiation of other<b> looked like this:

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

Here, your program would be ill-formed because other<b>::value is a type, not a value, but the compiler couldn't diagnose the error without actually doing the instantiation.

小梨窩很甜 2024-10-17 06:05:00

请注意,自从 C++11 中引入了 constexpr 函数,您就可以实现短路:

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>();
}

Note that since the introduction of constexpr functions in C++11, you can achieve short-circuiting:

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;
}

... though test_other() is undefined the compiler doesn't attempt to call it.

Unfortunately this doesn't work with consteval. In this case the first-level 'test facility' test itself must be a function:

template<bool b>
consteval bool test_other();

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

int main()
{
    bool value = test<true>();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文