2017-04-25 9 views
2

非型テンプレートパラメータとしてC文字列で失敗しましたデータベースからテンプレートパラメータを使用してデータを取得するコードが含まれています(メンバ変数は、そのようなテストを行う方が簡単だったので静的です)。 Type(名前も変更されます)を使用して、_Typeの束を結び付けます。 xとローカル変数としてyテンプレート引数置換は、私は私がそのような何かを行うことができるようになるタイプを作成しようとしている

gccxyは何のリンケージを持たないことを言います。

タイプの実装は、次のとおり

constexpr bool strings_equal(char const* a , char const* b) 
{ 
    return *a == *b && (*a == '\0' || strings_equal(a + 1, b + 1)); 
} 

template <typename T, const char* n> 
struct _Type { 
    using type = T; 
    static constexpr T value = T{}; 
    static constexpr const char* name = n; 
    template <const char* name, typename = typename std::enable_if<strings_equal(n, name)>::value> 
    T get() 
    { 
     return value; 
    } 
}; 
template <typename T> 
struct _Type2 : T { 
}; 
template <class... T> 
struct Type { 
    std::tuple<T...> vals; 
    template <unsigned idx, const char* name, bool end_ = true> 
    auto _get() -> typename decltype(std::get<idx + 1>(vals))::type 
    { 
     return decltype(std::get<idx + 1>(vals))::value; 
    } 
    template <unsigned idx, const char* name, bool end_> 
    auto _get() -> decltype(
     _get<(idx + 1), std::forward<const char*>(name), strings_equal(name, std::remove_reference<decltype(std::get<idx + 1>(vals))>::type::name)>()) 
    { 
     return _get<idx + 1, std::forward<const char*>(name), string_equal(name, std::remove_reference<decltype(std::get<idx + 1>(vals))>::type::name)>; 
    } 

    template <const char* name> 
    auto get() -> decltype(
     _get<0, std::forward<const char*>(name), strings_equal(name, std::remove_reference<decltype(std::get<0>(vals))>::type::name)>()) 
    { 
     return _get<0, name, string_equal(std::forward<const char*>(name), decltype(std::get<0>(vals))::name)>; 
    } 
}; 

このコードは、(コンパイル時)にエラーを生じさせます。

clangは私に、このエラーを与える:

test.cpp:60:23: error: no matching member function for call to 'get' 
    std::cout << truc.get<std::forward<const char*>(x)>() << std::endl; 
       ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
test.cpp:48:10: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'name' 
    auto get() -> decltype(
     ^
1 error generated. 

完全なコードとgccエラーがhere可能です。

このエラーを解決し、非タイプのテンプレートパラメータにローカル変数を使用できるようにするにはどうすればよいですか?

ありがとうございました。地元の文字列を使用して

EDIT は、(説明のために感謝@PasserBy)それらの連携に動作しません解決

EDIT 2 、Jarod42 @

+0

をコンパイルし、あなたは(http://coliru.stacked-crooked.com/a/4210e6d46bf41a0a)[その]のような実装を簡素化することがあります。 – Jarod42

+0

これは簡単で機能します!ありがとう! – nefas

答えて

1

ローカル変数への感謝は決してすることができます外部のつながりを持つ。これまでリンケージが重要な理由については、thisを参照してください。

外部リンケージのc-stringだけが翻訳単位で同じ値を持ち、変換単位間でパラメータが同じになるということが重要です。

次のコードは、BTW

constexpr const char x[] = "x"; 
constexpr const char y[] = "y"; 

template<typename T, typename U> 
struct Type {}; 

template<typename T, const char*> 
struct _Type {}; 

int main() 
{ 
    //good, external linkage 
    Type<_Type<int, x>, _Type<float, y>> t1; 

    //won't compile, string literal has internal linkage 
    //Type<_Type<int, "x">, _Type<float, "y">> t2; 

    static constexpr const char local[] = "x"; 
    //won't compile, local variables don't have external linkage 
    //Type<_Type<int, local>, _Type<float, local>> t3; 
} 
関連する問題