Feeds:
Posts
Comments

The VC++ 2013 compiler supports variadic templates. They are templates that can take a variable number of template arguments. In my opinion, it’s more a feature for library authors than for library consumers, so I am not sure how popular its use will be among end-user C++ developers. Here’s a very simple example that shows variadic templates in action.

// Variadic template declaration
template<typename... Args> class Test;

// Specialization 1
template<typename T> class Test<T>
{
public:
  T Data;
};

// Specialization 2
template<typename T1, typename T2> class Test<T1, T2>
{
public:
  T1 Left;
  T2 Right;
};

void Foo()
{
  Test<int> data;
  data.Data = 24;

  Test<int, int> twovalues;
  twovalues.Left = 12;
  twovalues.Right = 15;
}

The intellisense kicks in and works beautifully too when using variadic templates. I will be trying to blog more on the use of variadic templates in the near future.

VC++ 2013 now supports raw string literals. Note that it does not support Unicode string literals. A raw string literal allows you to avoid having to escape special characters which can be handy with HTML, XML, and regular expressions. Here’s an example usage.

auto s1 = R"(This is a "raw" string)";

Now s1 is a const char* containing the value – This is a “raw” string. It’s similar to the @ string literal support in C# although even that does not support embedded double quotes. So, what if you want to embed R”(…) in a string literal. In that case, you can use the following syntax.

auto s2 = R"QQ(Example: R"(This is my raw string)")QQ";

Now s2 contains – Example: R”(This is my raw string)”.

In this example, I’ve used QQ as a delimiter. This delimiter can be any string up to 16 characters in length. Raw string literals can contain newlines too.

auto s3 = R"(<tr>
<td>data</td>
</tr>)";

Eventually, whenever they add support for Unicode string literals as well, you will be able to combine them and have raw Unicode string literals.

If you have the VS 2013 preview, then setting up the C++ REST SDK is easy. Right-click on the project in Solution Explorer, bring up the References dialog, select Add New Reference, select Extensions, and pick the C++ REST Extension SDK for Windows Store apps. That’s all. No need to separately setup include and lib paths. In the preview release, the files are in C:\Program Files (x86)\Microsoft SDKs\Microsoft Cpp REST SDK for Visual Studio 2013 Preview\SDK. This would quite likely change in the RTM version.

Even if you don’t have VS 2013, Casablanca is now available as a NuGet package. So you can install it from there as well, although in that case it gets installed as a project specific package.

In VC++ 2013, you can have a boxed object as a member of a value type. Example code below.

value class Member sealed
{
public:
    String^ name;
    IBox<int>^ age;
};

Here’s some code showing how the type can be used.

Member member;
member.name = "Nish";
member.age = 80;
int age = member.age->Value;
member.age = nullptr;

Even in normal boxing/unboxing, when you use a safe_cast on a boxed object, eventually what happens is that a safe_cast to IBox<T> is performed and then the Value property accessed. Example, the following two snippets are semantically identical.

int y = 11;

// snippet 1
Object^ obj = y;
int y3 = safe_cast<int>(obj);

// snippet 2
IBox<int>^ boxedY = safe_cast<IBox<int>^>(obj);
int y2 = boxedY->Value;

Object::ToString was not virtual in VS 2012 and thus could not be overridden, and this was a bit of an inconvenience when databinding with XAML. Tarek Madkour’s Build 2013 talk on what’s new in VS 2013 for C++ Developers had a slide about overriding ToString. While that was exciting to see, I was a tad disappointed when I could not get it to compile under the VS 2013 preview build. The following code fails to compile.

ref class Person sealed
{
public:
    virtual String^ ToString() override
    {
        return "Test override";
    }
};

The error thrown is : Error 1 error C3668: ‘Person::ToString’ : method with override specifier ‘override’ did not override any base class methods

I am hoping that it just never made it to the preview release and that the RTM version will have it, as it can be quite handy to be able to override ToString, and not just in XAML scenarios.

The current release of Casablanca does not support progress reporting when reading from an HTTP stream, you only know when it’s completed – but, you can read chunk by chunk and get a percentage based on the total size that you can get off the header. Here’s a code snippet that shows one way of doing this with PPL tasks. It recursively calls the Repeat function until there’s nothing left to read, and the then() code in the original call is executed. So you still get a completed event while also being able to report progress. The code snippet does not do anything with the data, it just shows a percentage.

concurrency::task<void> Repeat(
  istream bodyStream, size_t chunkSize, 
  size_t lenRead, size_t contentLength)
{
	container_buffer<std::string> buffer;

	return concurrency::create_task(
    [=] { return bodyStream.read(buffer, chunkSize).get(); })
		.then([=](int bytesRead)
	{
		if(bytesRead > 0)
		{
			std::wcout << (lenRead + bytesRead) * 100 / contentLength 
                 << L"% downloaded"  << std::endl;
			return Repeat(bodyStream, chunkSize, lenRead + bytesRead, contentLength);
		}

		return concurrency::create_task([]{});
	});
}

// . . .

http_client client(L"http://www.codeproject.com");

client.request(methods::GET).then([](http_response response)
{
  if(response.status_code() == status_codes::OK)
  {
    auto bodyStream = response.body();		

    size_t contentLength = response.headers().content_length();
    std::wcout << L"Content length: " << contentLength << std::endl;            

    Repeat(bodyStream, 8192, 0, contentLength).then([]
    {
      std::wcout << L"Completed." << std::endl;            
    });
  }
});

Here’s some sample output:

Content length: 79025
3% downloaded
13% downloaded
17% downloaded
27% downloaded
31% downloaded
41% downloaded
42% downloaded
52% downloaded
58% downloaded
68% downloaded
68% downloaded
79% downloaded
79% downloaded
89% downloaded
91% downloaded
100% downloaded
Completed.

I am not a PPL expert so if you notice anything quirky about this, feel free to comment on it. Thanks.

Continuing on with Casablance, here’s a code snippet that shows how to POST JSON data to a web server.

json::value postData;
postData[L"name"] = json::value::string(L"Joe Smith");
postData[L"sport"] = json::value::string(L"Baseball");

http_client client(L"http://localhost:5540/api/values");

client.request(methods::POST, L"", postData.to_string().c_str(), 
  L"application/json").then([](http_response response)
{
  std::wcout <<  response.status_code() << std::endl;

  if(response.status_code() == status_codes::OK)
  {
    auto body = response.extract_string();		

    std::wcout << body.get().c_str();
  }
});

C++ does not have reflection, so unlike with .NET, you need to manually create the JSON from an object structure (which may seem like too much work if you’ve used JSON libraries in C# where the JSON is easily auto-generated using reflection). But it should not be too difficult to come up with some helper classes/methods that’ll make this easier for you.

Follow

Get every new post delivered to your Inbox.