2016-11-12 10 views
10

は私がWandboxに以下のコードを試してみました:std :: applyおよびconstant expression?

#include <array> 
#include <iostream> 
#include <tuple> 
#include <typeinfo> 
#include <functional> 
#include <utility> 


int main() 
{ 
    constexpr std::array<const char, 10> str{"123456789"}; 
    constexpr auto foo = std::apply([](auto... args) constexpr { std::integer_sequence<char, args...>{}; } , str); 
    std::cout << typeid(foo).name(); 
} 

とコンパイラがargs...は定数式ではないことを教えてくれました。 どうしたの?

+7

、あなたがconstexprの関数のパラメータを持つことができません。つまり、すべての関数はランタイムパラメータで呼び出すことができると想定しなければならず、ラムダは意味をなさない。 – krzaq

+0

@krzaqどういう残念... – Cu2S

答えて

4

すべてのconstexpr関数は、constexprとマークされていても、constexprとnotexの両方で有効である必要があります。

文字を非型テンプレートパラメータとして渡したconstexprリテラルの提案があります。その後、"hello"_bobを直接パラメータパックに展開できます。

もう1つの方法は、indexerのように、std::integral_constant<T, t>を何らかの仕組みでラムダに渡すことです。その後、Tへの変換は、変数がそうでない場合でもconstexprです。これはシーケンスへの"hello"であなたを助けません。

8

ファンクションパラメータには、constexprというラベルを付けることはできません。そのため、型のないテンプレート引数のように、定数式を必要とする場所では使用できません。

あなたがしようとしているようなことをするには、テンプレート引数に基づいて、何らかの種類のコンパイル時文字列処理が必要です。

5

何がstd::applyせずに行うことができますしたい:これはC++ 1Zに変更されていない限り

#include <array> 
#include <iostream> 
#include <tuple> 
#include <typeinfo> 
#include <functional> 
#include <utility> 
#include <type_traits> 

template <std::size_t N, class = std::make_index_sequence<N>> 
struct iterate; 

template <std::size_t N, std::size_t... Is> 
struct iterate<N, std::index_sequence<Is...>> { 
    template <class Lambda> 
    constexpr auto operator()(Lambda lambda) { 
     return lambda(std::integral_constant<std::size_t, Is>{}...); 
    } 
}; 

int main() 
{ 
    constexpr std::array<const char, 10> str{"123456789"}; 
    constexpr auto foo = iterate<str.size()>{}([](auto... is) constexpr { return std::integer_sequence<char, str[is]...>{}; }); 
    std::cout << typeid(foo).name(); 
} 

[live demo]

+2

私はそれがうまくいくと思っていますが、それはすべきですか? – krzaq

+0

私は実際にはそれがまだ分かってはいけないと考えています:/ –

+0

もしstrがメインの外で定義されていれば、それに疑問はありません... –

関連する問題