2015-05-11 15 views
7

derlemek değildir: kod çalışıyorNeden const referans çalışmaları ile constexpr nesnesini geçen değil değerine göre temelde derleme zamanında bir <code>std::array<></code> içine <code>std::integer_sequence<></code> eşler aşağıdaki kodu var

#include <iostream> 
#include <utility> 
#include <array> 

template<int...Is> 
constexpr auto make_array(const std::integer_sequence<int, Is...>& param) // this works */ 
// constexpr auto make_array(std::integer_sequence<int, Is...> param) // doesn't compile 
{ 
    return std::array<int, sizeof...(Is)> {Is...}; 
} 

int main() 
{ 
    constexpr std::integer_sequence<int, 1,2,3,4> iseq; 

    // If I pass by value, error: the value of 'iseq' is not usable in a constant expression 
    constexpr auto arr = make_array(iseq); 

    for(auto elem: arr) 
     std::cout << elem << " "; 
} 

zaman make_array argümanını const -referansı ile alır. Neden bu

error: the value of 'iseq' is not usable in a constant expression

constexpr auto arr = make_array(iseq); 

: Ben yorumladı doğrultusunda gibi değeri geçirmeden deneyin zaman, bu bir hata tükürür? Parametre iseq kesinlikle sabit bir ifadesidir, neden make_array bunu geçemez?

#include <iostream> 
#include <utility> 

struct Foo 
{ 
    int _m; 
    constexpr Foo(int m): _m(m){}; 
}; 

constexpr Foo factory_foo(int m) 
{ 
    return Foo{m}; 
} 

constexpr Foo copy_foo(Foo foo) 
{ 
    return foo; 
} 

int main() 
{ 
    constexpr Foo cxfoo = factory_foo(42); 
    constexpr Foo cpfoo = copy_foo(cxfoo); 
} 

DÜZENLEME MacPorts g ++ 5.1 kullanıyorum

: değeriyle geçen beklendiği gibi

Örneğin, kod aşağıdaki çalışır. clang ++ 3.5 kullanarak, ben bile (const atfen) ++ g ile derler kodu için bir hata mesajı alıyorum:

error: default initialization of an object of const type 'const std::integer_sequence' requires a user-provided default constructor

yüzden bir kullanıcı tarafından sağlanan varsayılan kurucu eksikliği ile bazı sorun vardır sanırım, ama en bu noktada neler olup bittiğini anlamıyorum.

+0

derleyici (ler) ve sürüm (ler). –

+0

@ShafikYaghmour g ++ 5.1, yakında clang üzerinde çalışacağız. Güncellenmiş düzenlemeye bakın, clang ++ 'const' referansıyla iletme durumunda bile bir hata yapıyor. Muhtemelen varsayılan ifadeler hakkında sabit ifadelerde bir şey eksik. – vsoftco

cevap

5

Sen iseq üzerinde bir başlatıcı eksik. Bunu eklemek zorunda: [dcl.constexpr] Gönderen

constexpr std::integer_sequence<int, 1,2,3,4> iseq{}; 
                ^^ 

:

A constexpr specifier used in an object declaration declares the object as const . Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.20). Otherwise, or if a constexpr specifier is used in a reference declaration, every fullexpression that appears in its initializer shall be a constant expression. [ Note: Each implicit conversion used in converting the initializer expressions and each constructor call used for the initialization is part of such a full-expression. —end note ]
[ Example:

struct pixel { 
    int x, y; 
}; 
constexpr pixel ur = { 1294, 1024 }; // OK 
constexpr pixel origin;    // error: initializer missing 

—end example ]

Üstelik Columbo sadece yetersiz olduğunu başlatıldı, comment ve answer onun içinde anlaşılacağı gibi. Bu constepxr nesne için (dcl.constexpr) gereksinimleri eksik bir açıklama vardır en uygun kesite sahip olması için biraz garip

If a program calls for the default initialization of an object of a const-qualified type T , T shall be a class type with a user-provided default constructor.

: [dcl.init] uygun olarak bir kullanıcı tarafından sağlanan kurucu de gereklidir, beyanı.

+0

Darn !!!! Bu kolay bir düzeltme oldu :) O zaman g ++ bir hata var. Ben sadece cehennem ++ 'nın bir hatayı tükettiği' olanq 'tanımını kontrol etmek için aklımdan bile geçemedim. (Zaten rapor değilse) @Columbo ilk Wandbox üzerinde BAŞ ile kontrol @vsoftco ++ – vsoftco

+0

Testere,. – Columbo

+0

Ben örtük const şey hakkında işaretlendiğinde alıntı – vsoftco

6

If a program calls for the default initialization of an object of a const-qualified type T , T shall be a class type with a user-provided default constructor.

Ancak integer_sequence herhangi bir kullanıcı tarafından sağlanan kurucular bulunmamaktadır ve constexpr değişkenler için const eder, buna bağlı olarak bir başlatıcı olmadan bu tür bir constexpr nesneyi tanımlamak olamaz. bir başlatıcı makes it compile on Clang ekleme
.

+0

Teşekkürler, bugün bir şey öğrendim! – vsoftco

İlgili konular