質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

884閲覧

コンテナの関数テンプレート引数での特殊化

退会済みユーザー

退会済みユーザー

総合スコア0

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/03/24 14:26

既出でしたらすみません。
型推論でコンテナが推論されているかつ、テンプレート引数の推論がstd::stringの時のみ特殊化を考えていたのですが、うまくいきません。
どうにか特殊化する方法はないでしょうか。

cpp

1template<typename T, typename = void> 2struct is_container : std::false_type {}; 3 4template<typename... Ts> 5struct is_container_helper {}; 6 7template<typename T> 8struct is_container< 9 T, 10 std::conditional_t< 11 false, 12 is_container_helper< 13 typename T::value_type, 14 typename T::size_type, 15 typename T::iterator, 16 typename T::const_iterator, 17 decltype(std::declval<T>().size()), 18 decltype(std::declval<T>().begin()), 19 decltype(std::declval<T>().end()), 20 decltype(std::declval<T>().cbegin()), 21 decltype(std::declval<T>().cend()), 22 decltype(std::declval<T>().back()) 23 >, 24 void 25 > 26> : public std::true_type {}; 27 28template <typename T> 29constexpr auto is_container_v = is_container<T>::value; 30 31template<typename T, std::enable_if_t<is_container_v<std::remove_reference_t<T>>, std::nullptr_t> = nullptr> 32auto f(T) { 33 std::cout << "call container" << std::endl; 34} 35 36/* 37そもそもエラー 38template <typename T> 39auto f(T<std::string>) { 40 std::cout << "call specialization" << std::endl; 41} 42*/ 43 44// エラーにはならないが呼ばれない 45template<template<typename Elem>typename T> 46auto f(T<std::string>) { 47 std::cout << "call specialization" << std::endl; 48} 49 50int main () { 51 // ともに"call container"が呼ばれる 52 f(std::vector<int>()); 53 f(std::vector<std::string>()); 54}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こう?

C++

1template<template<class Elem, class Allocator = std::allocator<Elem>>typename T> 2auto f(T<std::string>) { 3 std::cout << "call specialization" << std::endl; 4}

コンテナ判別が漏れていました…

C++

1template<template<class Elem, class = std::allocator<Elem>>typename T, std::enable_if_t<is_container_v<std::remove_reference_t<T<std::string>>>, std::nullptr_t> = nullptr> 2auto f(T<std::string>) { 3 std::cout << "call specialization" << std::endl; 4}

std::arrayにも対応させる

こんな感じ?

C++

1template<template<class, size_t>typename T, size_t Size, std::enable_if_t<is_container_v<std::remove_reference_t<T<std::string, Size>>>, std::nullptr_t> = nullptr> 2auto f(T<std::string, Size>) 3{ 4 std::cout << "call specialization size:" << Size << std::endl; 5}

二次元配列(std::array<std::array<std::string, 3>, 4>のようなもの

C++

1template<template<class, size_t>typename T, size_t Size1, size_t Size2, std::enable_if_t<is_container_v<std::remove_reference_t<T<std::string, Size1>>>, std::nullptr_t> = nullptr> 2auto f(T< T<std::string, Size1>, Size2>) 3{ 4 std::cout << "call specialization Size1:" << Size1 << " Size2:" << Size2 << std::endl; 5}

投稿2020/03/24 15:54

編集2020/03/26 17:29
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/03/25 10:50

回答ありがとうございます。 std::vectorだとうまくいくのですが、std::arrayにも対応させるのは難しいですかね…
退会済みユーザー

退会済みユーザー

2020/03/26 15:42 編集

すごく助かりました、ありがとうございます。 求めていた挙動をしました…勉強になりました… すみません、二次元配列(std::array<std::array<std::string, 3>, 4>のようなものでも可能ですか? 全然厳しければ流してください。 ちょっといただいた記述をもとに試してたのですがうまくいかず…
退会済みユーザー

退会済みユーザー

2020/03/27 12:08

ありがとうございました。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問