2016-04-10 38 views
2

Bu bir bilgisiz soru ise beni bağışlayın, ancak hala constexpr belirticiyi ne zaman ve nasıl kullanacağım konusunda kafamı kaydırıyorum. (msvc 14 ile derleme). Rasgele bir nesneyi bir "constexpr nesnesi" haline getirmenize izin veren basit bir temel sınıfta çalışıyorum. Bu şuna benzer:Türetilmiş bir sınıfın işlevinde Constexpr belirtecini kullanma

template<typename T> 
class basic_const { 
public: 

    explicit constexpr basic_const(const T& value) : data_(value) { } 

    template <typename...Args> 
    constexpr basic_const(Args&&...args) : data_(T(std::forward<Args>(args)...)) { } 

    virtual ~basic_const() = default; 

    constexpr const T& data() const noexcept { return data_; } 

private: 
    T data_; 
}; 

Her şey beklendiği gibi, ben başarıyla (besbelli) constexpr olarak nitelemek herhangi türde bir nesne oluşturabilir çalışır.

İşte sorun:
Bu sınıftan miras almaya çalıştığınızda, ek constexpr üye işlevlerini uygulayamıyorum, ancak katılabilirler.

class str_const : public basic_const<const char*> 
{ 
public: 

    template <std::size_t N> 
    constexpr str_const(const char(&str)[N]) : 
     basic_const(str), sz_(N) {} 
    ... 
    constexpr std::size_t size() const noexcept{ return sz_; } // error here 
    ... 
public: 
    std::size_t sz_; 
}; 

i türetilmiş bir sınıfta constexpr üye işlevlerini oluşturabilir miyim: Aşağıdaki kod i uygulamak ediyorum bir constexpr dize sınıfa ait?

cevap

2

Sorun, your answer'da yazdığınız gibi görünmüyor. Sorun, bir sanal yıkıcının varlığından (yani, non-trivial destructor) dolayı, kapatma sınıfının bir literal type olmamasıdır. gcc (mayın vurgulamak) tükürür:

error: enclosing class of constexpr non-static member function 'std::size_t str_const::size() const' is not a literal type

Live example with the error

yıkıcıdan virtual eleme çıkarın ve işe yarayacak.

Live example working

üye değişkenler için ek const s için gerek yoktur.

DÜZENLEME

clang ancak compiles your code just fine ... merak bu bir hata ise. Şimdi bunun gerçekten bir clang böceği olduğunu, bir virtual destructor is non-trivial olarak fark ettiniz, bu yüzden clang kodunuzu olduğu gibi derlememelidir.

+0

teşekkürler, temizlenmiş şeyler biraz! –

+0

@NowhereMan Rica ederim, güzel soru. Ben hala bir clang böcek doldurmak için en az bir örnek ile gelmeye çalışıyorum. – vsoftco

+0

Üye işlevlerinin yalnızca dizisel özellikler için bildirilen kısıtlama, C++ 11 sınırlaması olarak C++ 11 sınırlamasıyla C++ 11 ile sınırlandırıldı ve C++ 1484 ile birlikte tamamen kaldırıldı ve C++ 14'ten tamamen kaldırıldı. GCC burada yanlış, Clang doğru ve bu yüzden bu cevap yanlış. ; -D (DÜZENLEME: Değiştirilen özel ifadeler, [dcl.constexpr]/8; cümlede idi. * Bu fonksiyonun bir üyesi olduğu sınıf bir harfli olacaktır. * "Kaldırılmıştır.) – ildjarn

0

Mükemmel kabul edilebilir olanı ben de başarmak çalışıyorum görünüyor, türetilmiş sınıftaki üye değişkeni const için tabanı ve türetilmiş sınıfta hem de değişkenleri değiştirerek, const beyan edilmedi sorun giderildi.

İlgili konular