#include <iostream>
#include <string>
#include <vector>
#include <cassert>
using namespace std;

struct A {
  A(int &&) { cout << "create A" << endl; }
  A(A&&) { cout << "move A" << endl; }
  ~A(){ cout << "kill A" << endl; }
};

template <class T> struct B {
  T value;
  B() : value() { cout << "new B" << endl; }
  B(const T &__a) : value(__a) { cout << "create B" << endl; }
  B(const B &p) = default;
  B(B && o) = default;
  ~B(){ cout << "kill B" << endl; }; 
  template <class U, class = typename enable_if<is_convertible<U, T>::value>::type>
    B(U &&v) : value(std::forward<U>(v)) { 
      cout << "new forward initialized B" << endl; 
    }
};

void foo(B<const A&> a){  cout << "Using A" << endl; }

template<typename T>
void baz(const vector<B<T>> &test){
  cout << "In Baz: " << endl; 
  for(const auto &e : test) std::cout << e.value << endl;
}

int main(){
  cout << "Foo test case:" << endl;
  foo( {123} );
  
  cout << "\nThis works as expexted::" << endl;
  foo( A(123) );

  // passing strings around works
  cout << "\nString test case:" << endl;
  baz<std::string>({"Hello", "World"});

  // passing const reference doesn't
  cout << "\nSecond string test case:" << endl;
  baz<const std::string &>({"Hello", "World"});
}
