【问题标题】:Constexpr value as nontype template parameter of pointer typeconstexpr 值作为指针类型的非类型模板参数
【发布时间】:2019-08-13 20:17:28
【问题描述】:

以下code

#include <iostream>
#include <initializer_list>

using namespace std;


constexpr initializer_list<int> list = {1, 2, 3};

template<const int* begin, const int* end>
bool contains(int v)
{
    if constexpr(begin != end)
    {
        if (*begin = v)
            return true;
        else
            return contains<next(begin), end>(v);
    }
    return false;
}


int main()
{
    cout << contains<list.begin(), list.end()>(2);
    return 0;
}

产生一些非常奇怪的错误信息:

main.cpp: In function 'int main()':
main.cpp:25:49: error: no matching function for call to 'contains<list.std::initializer_list<int>::begin(), list.std::initializer_list<int>::end()>(int)'
     cout << contains<list.begin(), list.end()>(2);
                                                 ^
main.cpp:10:6: note: candidate: 'template<const int* begin, const int* end> bool contains(int)'
 bool contains(int v)
      ^~~~~~~~
main.cpp:10:6: note:   template argument deduction/substitution failed:
main.cpp:25:49: error: the address of '._86' is not a valid template argument
     cout << contains<list.begin(), list.end()>(2);
                                                 ^
main.cpp:25:49: error: 'list.std::initializer_list<int>::end()' is not a valid template argument for 'const int*' because it is not the address of a variable

我相信这个可以编译,因为编译器在编译时拥有所有信息:list 是 constexpr,它的 beginendnext 也是如此。那么是什么阻止了它的工作呢?

【问题讨论】:

    标签: c++ templates c++17 constexpr


    【解决方案1】:

    初始化器列表对象包含一个指向 3 个 ints 数组的指针,这些数组实际上具有值 1、2、3。当您调用 .begin() 时,将返回指向第一个元素(值为 1)的指针.但是,不允许使用指向数组元素的指针作为模板参数,因为标准规定指针类型的模板参数不得指向“子对象”([temp.arg.nontype]/2.1)。不过,我不确定为什么会存在这种限制。

    【讨论】:

    • 存在限制是因为实现它需要更改名称修饰以支持将子对象标识符序列化为名称,简单地说,这不会很有趣。
    猜你喜欢
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 2016-03-01
    • 2019-04-24
    • 1970-01-01
    • 2017-09-17
    相关资源
    最近更新 更多