Template template argument deduction failure with GCC (works with MSVC)












1














I have the following reasonably simple function template:



template <class OrderedSetType, template<class> class SupersetType>
OrderedSetType f(const SupersetType<OrderedSetType>& superset)
{
return OrderedSetType();
}


It's called like this:



f(std::vector<std::string>());


And the compiler fails to deduce the template parameter. The diagnostic message isn't particularly helpful:



<source>: In function 'int main()':

<source>:12:33: error: no matching function for call to 'f(std::vector<std::__cxx11::basic_string<char> >)'

f(std::vector<std::string>());

^

<source>:5:16: note: candidate: template<class OrderedSetType, template<class> class SupersetType> OrderedSetType f(const SupersetType<OrderedSetType>&)

OrderedSetType f(const SupersetType<OrderedSetType>& superset)

^

<source>:5:16: note: template argument deduction/substitution failed:

<source>:12:33: note: template parameters of a template template argument are inconsistent with other deduced template arguments

f(std::vector<std::string>());

^


Why does the error occur? Happens with GCC 7.3 with -std=c++14, does not happen with -std=c++17. Which changes in the C++ 17 standard allowed for this code to compile? And can I make it compile for C++14?



Here's the live demo: https://godbolt.org/g/89BTzz



Specifying the template arguments explicitly doesn't help, by the way.



P. S. In the meantime, MSVC has no problems with this piece of code, but clang 5 and 6 cannot compile it even in C++17 mode. So either clang has a bug and fails to compile standard-compliant code, or GCC has a bug and successfully compiles code that it shouldn't (with -std=c++17).










share|improve this question





























    1














    I have the following reasonably simple function template:



    template <class OrderedSetType, template<class> class SupersetType>
    OrderedSetType f(const SupersetType<OrderedSetType>& superset)
    {
    return OrderedSetType();
    }


    It's called like this:



    f(std::vector<std::string>());


    And the compiler fails to deduce the template parameter. The diagnostic message isn't particularly helpful:



    <source>: In function 'int main()':

    <source>:12:33: error: no matching function for call to 'f(std::vector<std::__cxx11::basic_string<char> >)'

    f(std::vector<std::string>());

    ^

    <source>:5:16: note: candidate: template<class OrderedSetType, template<class> class SupersetType> OrderedSetType f(const SupersetType<OrderedSetType>&)

    OrderedSetType f(const SupersetType<OrderedSetType>& superset)

    ^

    <source>:5:16: note: template argument deduction/substitution failed:

    <source>:12:33: note: template parameters of a template template argument are inconsistent with other deduced template arguments

    f(std::vector<std::string>());

    ^


    Why does the error occur? Happens with GCC 7.3 with -std=c++14, does not happen with -std=c++17. Which changes in the C++ 17 standard allowed for this code to compile? And can I make it compile for C++14?



    Here's the live demo: https://godbolt.org/g/89BTzz



    Specifying the template arguments explicitly doesn't help, by the way.



    P. S. In the meantime, MSVC has no problems with this piece of code, but clang 5 and 6 cannot compile it even in C++17 mode. So either clang has a bug and fails to compile standard-compliant code, or GCC has a bug and successfully compiles code that it shouldn't (with -std=c++17).










    share|improve this question



























      1












      1








      1







      I have the following reasonably simple function template:



      template <class OrderedSetType, template<class> class SupersetType>
      OrderedSetType f(const SupersetType<OrderedSetType>& superset)
      {
      return OrderedSetType();
      }


      It's called like this:



      f(std::vector<std::string>());


      And the compiler fails to deduce the template parameter. The diagnostic message isn't particularly helpful:



      <source>: In function 'int main()':

      <source>:12:33: error: no matching function for call to 'f(std::vector<std::__cxx11::basic_string<char> >)'

      f(std::vector<std::string>());

      ^

      <source>:5:16: note: candidate: template<class OrderedSetType, template<class> class SupersetType> OrderedSetType f(const SupersetType<OrderedSetType>&)

      OrderedSetType f(const SupersetType<OrderedSetType>& superset)

      ^

      <source>:5:16: note: template argument deduction/substitution failed:

      <source>:12:33: note: template parameters of a template template argument are inconsistent with other deduced template arguments

      f(std::vector<std::string>());

      ^


      Why does the error occur? Happens with GCC 7.3 with -std=c++14, does not happen with -std=c++17. Which changes in the C++ 17 standard allowed for this code to compile? And can I make it compile for C++14?



      Here's the live demo: https://godbolt.org/g/89BTzz



      Specifying the template arguments explicitly doesn't help, by the way.



      P. S. In the meantime, MSVC has no problems with this piece of code, but clang 5 and 6 cannot compile it even in C++17 mode. So either clang has a bug and fails to compile standard-compliant code, or GCC has a bug and successfully compiles code that it shouldn't (with -std=c++17).










      share|improve this question















      I have the following reasonably simple function template:



      template <class OrderedSetType, template<class> class SupersetType>
      OrderedSetType f(const SupersetType<OrderedSetType>& superset)
      {
      return OrderedSetType();
      }


      It's called like this:



      f(std::vector<std::string>());


      And the compiler fails to deduce the template parameter. The diagnostic message isn't particularly helpful:



      <source>: In function 'int main()':

      <source>:12:33: error: no matching function for call to 'f(std::vector<std::__cxx11::basic_string<char> >)'

      f(std::vector<std::string>());

      ^

      <source>:5:16: note: candidate: template<class OrderedSetType, template<class> class SupersetType> OrderedSetType f(const SupersetType<OrderedSetType>&)

      OrderedSetType f(const SupersetType<OrderedSetType>& superset)

      ^

      <source>:5:16: note: template argument deduction/substitution failed:

      <source>:12:33: note: template parameters of a template template argument are inconsistent with other deduced template arguments

      f(std::vector<std::string>());

      ^


      Why does the error occur? Happens with GCC 7.3 with -std=c++14, does not happen with -std=c++17. Which changes in the C++ 17 standard allowed for this code to compile? And can I make it compile for C++14?



      Here's the live demo: https://godbolt.org/g/89BTzz



      Specifying the template arguments explicitly doesn't help, by the way.



      P. S. In the meantime, MSVC has no problems with this piece of code, but clang 5 and 6 cannot compile it even in C++17 mode. So either clang has a bug and fails to compile standard-compliant code, or GCC has a bug and successfully compiles code that it shouldn't (with -std=c++17).







      c++ c++14 c++17 template-deduction template-templates






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 21:53









      max66

      34.3k63762




      34.3k63762










      asked Jun 24 at 9:56









      Violet Giraffe

      14.3k26131240




      14.3k26131240
























          3 Answers
          3






          active

          oldest

          votes


















          2














          Try with



          template <template <typename...> class SupersetType,
          typename FirstT, typename ... OthersTs>
          FirstT f (SupersetType<FirstT, OthersTs...> const & superset)
          { return FirstT{}; }


          or also



          template <template <typename...> class SupersetType, typename FirstT>
          FirstT f (SupersetType<FirstT> const & superset)
          { return FirstT{}; }


          The problem is that std::vector doesn't accept only a type but two; the second is an allocator with a default value.



          So you have to take in count this problem.



          Obviously you can write f() with a template-template parameter that accept only two types



          template <template <typename, typename> class SupersetType,
          typename FirstT, typename SecondT>
          FirstT f (SupersetType<FirstT, SecondT> const & superset)
          { return FirstT{}; }


          but if you use a template parameter that accept a variadic list of types, you have a more flexible f() (that match more containers)






          share|improve this answer























          • Ugh, the allocator strikes again. I keep forgetting about it. Thank you.
            – Violet Giraffe
            Jun 24 at 10:17





















          2















          Which changes in the C++ 17 standard allowed for this code to compile?




          You're declaring the template template parameter SupersetType contaning only one template parameter, but the template template argument std::vector<std::string> has two, i.e. std::string and the default template argument std::allocator<string>. Before C++17 they don't match and leads to error (then you have to make them match to solve the issue), since C++17 (CWG 150) it's allowed; i.e. the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters.




          template<class T> class A { /* ... */ };
          template<class T, class U = T> class B { /* ... */ };
          template <class ...Types> class C { /* ... */ };

          template<template<class> class P> class X { /* ... */ };
          X<A> xa; // OK
          X<B> xb; // OK in C++17 after CWG 150
          // Error earlier: not an exact match
          X<C> xc; // OK in C++17 after CWG 150
          // Error earlier: not an exact match






          share|improve this answer























          • So, the change allowed the compiler to treat B as if it only has one template parameter (because the other one has a default value)?
            – Violet Giraffe
            Jun 24 at 10:23










          • @VioletGiraffe Yes.
            – songyuanyao
            Jun 24 at 10:25



















          1














          While this doesn't provide an answer to your problem, it provide an alternative.



          Remember that all standard container have a public type named value_type. That means you could easily skip the template template and only have something like



          template<typename ContainerT>
          typename ContainerT::value_type f(ContainerT const& superset)
          {
          return typename ContainerT::value_type();
          }


          As long as your SupersetType follows the standard containers with a value_type member, it should work.






          share|improve this answer

















          • 1




            Good point, but I wanted it to be more generic and support containers that have only begin() / end() and don't necessarily define value_type.
            – Violet Giraffe
            Jun 24 at 10:08











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51008792%2ftemplate-template-argument-deduction-failure-with-gcc-works-with-msvc%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          Try with



          template <template <typename...> class SupersetType,
          typename FirstT, typename ... OthersTs>
          FirstT f (SupersetType<FirstT, OthersTs...> const & superset)
          { return FirstT{}; }


          or also



          template <template <typename...> class SupersetType, typename FirstT>
          FirstT f (SupersetType<FirstT> const & superset)
          { return FirstT{}; }


          The problem is that std::vector doesn't accept only a type but two; the second is an allocator with a default value.



          So you have to take in count this problem.



          Obviously you can write f() with a template-template parameter that accept only two types



          template <template <typename, typename> class SupersetType,
          typename FirstT, typename SecondT>
          FirstT f (SupersetType<FirstT, SecondT> const & superset)
          { return FirstT{}; }


          but if you use a template parameter that accept a variadic list of types, you have a more flexible f() (that match more containers)






          share|improve this answer























          • Ugh, the allocator strikes again. I keep forgetting about it. Thank you.
            – Violet Giraffe
            Jun 24 at 10:17


















          2














          Try with



          template <template <typename...> class SupersetType,
          typename FirstT, typename ... OthersTs>
          FirstT f (SupersetType<FirstT, OthersTs...> const & superset)
          { return FirstT{}; }


          or also



          template <template <typename...> class SupersetType, typename FirstT>
          FirstT f (SupersetType<FirstT> const & superset)
          { return FirstT{}; }


          The problem is that std::vector doesn't accept only a type but two; the second is an allocator with a default value.



          So you have to take in count this problem.



          Obviously you can write f() with a template-template parameter that accept only two types



          template <template <typename, typename> class SupersetType,
          typename FirstT, typename SecondT>
          FirstT f (SupersetType<FirstT, SecondT> const & superset)
          { return FirstT{}; }


          but if you use a template parameter that accept a variadic list of types, you have a more flexible f() (that match more containers)






          share|improve this answer























          • Ugh, the allocator strikes again. I keep forgetting about it. Thank you.
            – Violet Giraffe
            Jun 24 at 10:17
















          2












          2








          2






          Try with



          template <template <typename...> class SupersetType,
          typename FirstT, typename ... OthersTs>
          FirstT f (SupersetType<FirstT, OthersTs...> const & superset)
          { return FirstT{}; }


          or also



          template <template <typename...> class SupersetType, typename FirstT>
          FirstT f (SupersetType<FirstT> const & superset)
          { return FirstT{}; }


          The problem is that std::vector doesn't accept only a type but two; the second is an allocator with a default value.



          So you have to take in count this problem.



          Obviously you can write f() with a template-template parameter that accept only two types



          template <template <typename, typename> class SupersetType,
          typename FirstT, typename SecondT>
          FirstT f (SupersetType<FirstT, SecondT> const & superset)
          { return FirstT{}; }


          but if you use a template parameter that accept a variadic list of types, you have a more flexible f() (that match more containers)






          share|improve this answer














          Try with



          template <template <typename...> class SupersetType,
          typename FirstT, typename ... OthersTs>
          FirstT f (SupersetType<FirstT, OthersTs...> const & superset)
          { return FirstT{}; }


          or also



          template <template <typename...> class SupersetType, typename FirstT>
          FirstT f (SupersetType<FirstT> const & superset)
          { return FirstT{}; }


          The problem is that std::vector doesn't accept only a type but two; the second is an allocator with a default value.



          So you have to take in count this problem.



          Obviously you can write f() with a template-template parameter that accept only two types



          template <template <typename, typename> class SupersetType,
          typename FirstT, typename SecondT>
          FirstT f (SupersetType<FirstT, SecondT> const & superset)
          { return FirstT{}; }


          but if you use a template parameter that accept a variadic list of types, you have a more flexible f() (that match more containers)







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jun 24 at 10:13

























          answered Jun 24 at 10:02









          max66

          34.3k63762




          34.3k63762












          • Ugh, the allocator strikes again. I keep forgetting about it. Thank you.
            – Violet Giraffe
            Jun 24 at 10:17




















          • Ugh, the allocator strikes again. I keep forgetting about it. Thank you.
            – Violet Giraffe
            Jun 24 at 10:17


















          Ugh, the allocator strikes again. I keep forgetting about it. Thank you.
          – Violet Giraffe
          Jun 24 at 10:17






          Ugh, the allocator strikes again. I keep forgetting about it. Thank you.
          – Violet Giraffe
          Jun 24 at 10:17















          2















          Which changes in the C++ 17 standard allowed for this code to compile?




          You're declaring the template template parameter SupersetType contaning only one template parameter, but the template template argument std::vector<std::string> has two, i.e. std::string and the default template argument std::allocator<string>. Before C++17 they don't match and leads to error (then you have to make them match to solve the issue), since C++17 (CWG 150) it's allowed; i.e. the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters.




          template<class T> class A { /* ... */ };
          template<class T, class U = T> class B { /* ... */ };
          template <class ...Types> class C { /* ... */ };

          template<template<class> class P> class X { /* ... */ };
          X<A> xa; // OK
          X<B> xb; // OK in C++17 after CWG 150
          // Error earlier: not an exact match
          X<C> xc; // OK in C++17 after CWG 150
          // Error earlier: not an exact match






          share|improve this answer























          • So, the change allowed the compiler to treat B as if it only has one template parameter (because the other one has a default value)?
            – Violet Giraffe
            Jun 24 at 10:23










          • @VioletGiraffe Yes.
            – songyuanyao
            Jun 24 at 10:25
















          2















          Which changes in the C++ 17 standard allowed for this code to compile?




          You're declaring the template template parameter SupersetType contaning only one template parameter, but the template template argument std::vector<std::string> has two, i.e. std::string and the default template argument std::allocator<string>. Before C++17 they don't match and leads to error (then you have to make them match to solve the issue), since C++17 (CWG 150) it's allowed; i.e. the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters.




          template<class T> class A { /* ... */ };
          template<class T, class U = T> class B { /* ... */ };
          template <class ...Types> class C { /* ... */ };

          template<template<class> class P> class X { /* ... */ };
          X<A> xa; // OK
          X<B> xb; // OK in C++17 after CWG 150
          // Error earlier: not an exact match
          X<C> xc; // OK in C++17 after CWG 150
          // Error earlier: not an exact match






          share|improve this answer























          • So, the change allowed the compiler to treat B as if it only has one template parameter (because the other one has a default value)?
            – Violet Giraffe
            Jun 24 at 10:23










          • @VioletGiraffe Yes.
            – songyuanyao
            Jun 24 at 10:25














          2












          2








          2







          Which changes in the C++ 17 standard allowed for this code to compile?




          You're declaring the template template parameter SupersetType contaning only one template parameter, but the template template argument std::vector<std::string> has two, i.e. std::string and the default template argument std::allocator<string>. Before C++17 they don't match and leads to error (then you have to make them match to solve the issue), since C++17 (CWG 150) it's allowed; i.e. the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters.




          template<class T> class A { /* ... */ };
          template<class T, class U = T> class B { /* ... */ };
          template <class ...Types> class C { /* ... */ };

          template<template<class> class P> class X { /* ... */ };
          X<A> xa; // OK
          X<B> xb; // OK in C++17 after CWG 150
          // Error earlier: not an exact match
          X<C> xc; // OK in C++17 after CWG 150
          // Error earlier: not an exact match






          share|improve this answer















          Which changes in the C++ 17 standard allowed for this code to compile?




          You're declaring the template template parameter SupersetType contaning only one template parameter, but the template template argument std::vector<std::string> has two, i.e. std::string and the default template argument std::allocator<string>. Before C++17 they don't match and leads to error (then you have to make them match to solve the issue), since C++17 (CWG 150) it's allowed; i.e. the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters.




          template<class T> class A { /* ... */ };
          template<class T, class U = T> class B { /* ... */ };
          template <class ...Types> class C { /* ... */ };

          template<template<class> class P> class X { /* ... */ };
          X<A> xa; // OK
          X<B> xb; // OK in C++17 after CWG 150
          // Error earlier: not an exact match
          X<C> xc; // OK in C++17 after CWG 150
          // Error earlier: not an exact match







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jun 24 at 10:31

























          answered Jun 24 at 10:21









          songyuanyao

          89.8k11170234




          89.8k11170234












          • So, the change allowed the compiler to treat B as if it only has one template parameter (because the other one has a default value)?
            – Violet Giraffe
            Jun 24 at 10:23










          • @VioletGiraffe Yes.
            – songyuanyao
            Jun 24 at 10:25


















          • So, the change allowed the compiler to treat B as if it only has one template parameter (because the other one has a default value)?
            – Violet Giraffe
            Jun 24 at 10:23










          • @VioletGiraffe Yes.
            – songyuanyao
            Jun 24 at 10:25
















          So, the change allowed the compiler to treat B as if it only has one template parameter (because the other one has a default value)?
          – Violet Giraffe
          Jun 24 at 10:23




          So, the change allowed the compiler to treat B as if it only has one template parameter (because the other one has a default value)?
          – Violet Giraffe
          Jun 24 at 10:23












          @VioletGiraffe Yes.
          – songyuanyao
          Jun 24 at 10:25




          @VioletGiraffe Yes.
          – songyuanyao
          Jun 24 at 10:25











          1














          While this doesn't provide an answer to your problem, it provide an alternative.



          Remember that all standard container have a public type named value_type. That means you could easily skip the template template and only have something like



          template<typename ContainerT>
          typename ContainerT::value_type f(ContainerT const& superset)
          {
          return typename ContainerT::value_type();
          }


          As long as your SupersetType follows the standard containers with a value_type member, it should work.






          share|improve this answer

















          • 1




            Good point, but I wanted it to be more generic and support containers that have only begin() / end() and don't necessarily define value_type.
            – Violet Giraffe
            Jun 24 at 10:08
















          1














          While this doesn't provide an answer to your problem, it provide an alternative.



          Remember that all standard container have a public type named value_type. That means you could easily skip the template template and only have something like



          template<typename ContainerT>
          typename ContainerT::value_type f(ContainerT const& superset)
          {
          return typename ContainerT::value_type();
          }


          As long as your SupersetType follows the standard containers with a value_type member, it should work.






          share|improve this answer

















          • 1




            Good point, but I wanted it to be more generic and support containers that have only begin() / end() and don't necessarily define value_type.
            – Violet Giraffe
            Jun 24 at 10:08














          1












          1








          1






          While this doesn't provide an answer to your problem, it provide an alternative.



          Remember that all standard container have a public type named value_type. That means you could easily skip the template template and only have something like



          template<typename ContainerT>
          typename ContainerT::value_type f(ContainerT const& superset)
          {
          return typename ContainerT::value_type();
          }


          As long as your SupersetType follows the standard containers with a value_type member, it should work.






          share|improve this answer












          While this doesn't provide an answer to your problem, it provide an alternative.



          Remember that all standard container have a public type named value_type. That means you could easily skip the template template and only have something like



          template<typename ContainerT>
          typename ContainerT::value_type f(ContainerT const& superset)
          {
          return typename ContainerT::value_type();
          }


          As long as your SupersetType follows the standard containers with a value_type member, it should work.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jun 24 at 10:02









          Some programmer dude

          294k24248410




          294k24248410








          • 1




            Good point, but I wanted it to be more generic and support containers that have only begin() / end() and don't necessarily define value_type.
            – Violet Giraffe
            Jun 24 at 10:08














          • 1




            Good point, but I wanted it to be more generic and support containers that have only begin() / end() and don't necessarily define value_type.
            – Violet Giraffe
            Jun 24 at 10:08








          1




          1




          Good point, but I wanted it to be more generic and support containers that have only begin() / end() and don't necessarily define value_type.
          – Violet Giraffe
          Jun 24 at 10:08




          Good point, but I wanted it to be more generic and support containers that have only begin() / end() and don't necessarily define value_type.
          – Violet Giraffe
          Jun 24 at 10:08


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51008792%2ftemplate-template-argument-deduction-failure-with-gcc-works-with-msvc%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Full-time equivalent

          Bicuculline

          さくらももこ