这样将const T&传递给constexpr成员函数

时间:2019-12-04 16:59:20

标签: c++ constexpr

我正在尝试修复一些库代码,其中的精简版本看起来像这样:

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

由于以下原因,以上代码无法在GCC中编译:

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

关于constexpr成员函数中的this的规则是什么?是否要遵循为功能参数指定的规则?是否有特殊限制?

我将如何解决此错误?如果只是格式化程序结构,我将使用RangeT&&std::move,因为据我所知,视图根据定义可以在O(1)中复制。我不知道如何在混合类型擦除步骤中做到这一点...

预先感谢, 理查德

2 个答案:

答案 0 :(得分:1)

我认为这与# config/schedule.rb set :environment, 'development' 没有任何关系。

您有对constexpr const的引用,并且您试图在其上调用非RangeT成员函数(constbegin()

如果您愿意,提供end()重载(和/或const / cbegin()变体)。

答案 1 :(得分:1)

在您的代码中,作为开始和结束的不是const函数,如果没有“丢弃限定符”,this指针就不能指向const对象。

通过创建函数constthis指针可以指向const对象。

https://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions

https://en.cppreference.com/w/cpp/language/this

https://godbolt.org/z/3_wKh9