C++ 通过常数T&;这是一个constexpr成员函数

C++ 通过常数T&;这是一个constexpr成员函数,c++,constexpr,C++,Constexpr,我正在尝试修复一些库代码,其中简化的最低版本如下所示: #include <iostream> template <typename RangeT> struct formatter { constexpr void format(const RangeT& values) {

我正在尝试修复一些库代码,其中简化的最低版本如下所示:

 #include <iostream>

 template <typename RangeT>                                          
 struct formatter {                               
     constexpr void format(const RangeT& values) {    
         for (auto it = values.begin(), end = values.end(); it != end; ++it) { 
             std::cout << it << "\n";                
         }                                                                       
     }                                    
 }; 

template <typename RangeT, typename Formatter> 
struct type_erased {                                                       
    static void format(const void* arg) {                                
        Formatter f;                   
        f.format(*static_cast<const RangeT*>(arg)); 
    }                                                  
};                                                                 

struct view {   
    int count_;                                

    constexpr View(int count) : count_(count) {}  

    constexpr int 
    begin() { return 0; }                   

    constexpr int                                                    
    end() { return -1; } 
};                      

int                                                         
main()                                                         
{                               
    View view(5);       
    void* ptr = static_cast<void*>(&view);                          
    type_erased<View, formatter<View>>::format(ptr); 
}                                                                       
#包括
模板
结构格式化程序{
constexpr void格式(const range和values){
对于(auto it=values.begin(),end=values.end();it!=end;++it){

std::cout我认为这与
constexpr
没有任何关系

您有一个对
const
RangeT
的引用,并且您正试图在其上调用非
const
成员函数(
begin()
end()


如果您想允许,请提供
const
重载(和/或
cbegin()
/
cend()
变体)。

我认为这与
constepr
无关

您有一个对
const
RangeT
的引用,并且您正试图在其上调用非
const
成员函数(
begin()
end()


如果您想允许,请提供
const
重载(和/或
cbegin()
/
cend()
变量)。

在您的代码中,因为begin和end不是const函数,
指针不能指向
const
对象,除非“放弃限定符”

通过使函数
const
那么
这个
指针可以指向
const
对象


在您的代码中,因为开始和结束不是常量函数,
指针不能指向
常量
对象,除非“放弃限定符”

通过使函数
const
那么
这个
指针可以指向
const
对象


我不认为这是constexpr的问题,因为它是使用begin()和end()的问题。使用cbegin()和cend()。@rianquin或
const auto it
使用
const auto
会产生相同的结果(即相同的错误)。std::experional::ranges::filter\u view(这是这里的实际类型)没有cbegin/cend。GCC Trunk使begin和end const函数都可以编译。确实可以编译。换句话说,这些函数不能接受const void*/const auto¶meters…我不认为这是constepr的问题,因为这是使用begin()和end()的问题。使用cbegin()和cend()@rianquin或
const auto it
使用
const auto
会产生相同的结果(即相同的错误)。std::experimental::ranges::filter_视图(此处为实际类型)没有cbegin/cend。GCC主干同时生成begin和end const函数,使其能够编译。事实上,这是可以编译的。换句话说,这些函数不能接受const void*/const auto¶meters…不幸的是,似乎范围(或至少是视图)太大了不要实现const变量-这是不可行的。但是您的答案仍然提供了解释,所以我将其标记为已接受的答案。这是一个遗憾:(不幸的是,似乎范围(或至少视图)太大了)不要实现const变量-使其不可行。但是您的答案仍然提供了解释,因此我将其标记为已接受的答案。这很遗憾:(
../src/view.cpp: In instantiation of ‘constexpr void formatter<RangeT>::format(const RangeT&) [with RangeT = View]’:
../src/view.cpp:21:9:   required from ‘static void type_erased<RangeT, Formatter>::format(const void*) [with RangeT = View; Formatter = formatter<View>]’
../src/view.cpp:43:41:   required from here
../src/view.cpp:11:15: error: passing ‘const View’ as ‘this’ argument discards qualifiers [-fpermissive]
   11 |     for (auto it = values.begin(), end = values.end(); it != end; ++it) {
  |               ^~
../src/view.cpp:31:5: note:   in call to ‘constexpr int View::begin()’
   31 |     begin() { return 0; }
  |     ^~~~~
../src/view.cpp:11:36: error: passing ‘const View’ as ‘this’ argument discards qualifiers [-fpermissive]
   11 |     for (auto it = values.begin(), end = values.end(); it != end; ++it) {
  |                                    ^~~
../src/view.cpp:34:5: note:   in call to ‘constexpr int View::end()’
   34 |     end() { return -1; }