【问题标题】:When are constexpr function templates instantiated?什么时候实例化 constexpr 函数模板?
【发布时间】:2016-10-07 12:43:24
【问题描述】:

我正在制定一项提案,以使功能性标头功能 constexpr。 (std::invoke, std::reference_wrapper, std::bind, std::mem_fn, std::not_fn)

我了解到添加 constexpr 会破坏现有代码,因为 constexpr 函数会被急切地实例化。

template<class T>
int f(T){
    return T::not_existing_member;
}

template<class T>
constexpr int g(T){
    return T::not_existing_member;
}

int main(){
    decltype(f(0)) a; // Well-formed
    decltype(g(0)) b; // Ill-formed if the function body is instantiated
}

GCC 编译这段代码,clang 没有。我在my proposal 中描述了如何使用std::bind 的示例处理带有重载的急切实例化。

你能告诉我在标准中什么时候必须以及什么时候允许实例化一个函数模板?

更准确地说,我想知道在以下示例中,GCC 和 clang 的相同行为是由标准强制执行还是由实现定义:

template<class T>
struct Foo{
    constexpr int f(){
        return 0;
    }

    constexpr int f()const{
        return T::not_existing_member;
    }
};

int main(){
    /* constexpr */ Foo<int> foo;
    foo.f(); // Ill-formed with, Well-formed without constexpr by the standard?
}

如果foo 不是constexpr,则GCC 和clang 都会编译代码,如果是则都拒绝它。

【问题讨论】:

    标签: c++ templates instantiation constexpr


    【解决方案1】:

    示例 #1 处于活动状态 CWG issue 1581。目前还没有完全指定正确的行为应该是什么。方向似乎是constexpr 实例化应该是急切的,但这需要在未来的某个时候加以澄清。

    示例 #2 很简单:调用 int Foo&lt;int&gt;::f() const 格式不正确。当您的foo 对象是const 而不是const 时不会发生这种情况。类模板的成员函数只在使用时实例化,如果你的Foo&lt;int&gt;对象不是const,我们永远不会实例化const成员函数,所以代码格式正确。 constexpr 在这里不相关。

    【讨论】:

    • 啊,是的。我在推理示例 #2 时出错。由于 'foo' 是 'constexpr',它当然也变成了 'const',所以直接调用了 'const' 重载。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多