By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,949 Members | 1,563 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,949 IT Pros & Developers. It's quick & easy.

partial specialized templated classes

P: n/a
Hi,

I'm working on a thin libcurl layer. Therefore I have the following classes:

template<typename T, long CURLOPT_ID>
class CurlOption: boost::noncopyable {
public:
typedef typename boost::call_traits<T>::param_type param_type;
....
public:
// constructors:
CurlOption() {}
CurlOption(param_type v) : m_value(v) {}

public:
long option() const { return CURLOPT_ID; }
result_type parameter() { return m_value; }
void setopt(CURL* handle);

private:
value_type m_value;
};

and the specialized for the templated arguments T (ether bool, long,
std::string etc.):

template<long CURLOPT_ID>
class CurlOption<bool, CURLOPT_ID{
public:
void setopt(CURL* handle) {
curl_easy_setopt(handle,
this->option(), this->value() ? 1 : 0);
}
};

e.g. used like

struct CurlOpt {
typedef CurlOption<bool, CURLOPT_VERBOSE> Verbose;

};

and than the cURL handle class self using a double dispatch approach:

class EasyCurl : boost::noncopyable
{
public:
...
template<typename T, long ID>
void setopt(const CurlOption<T, ID>& opt) {
opt.setopt(m_curl);
}

private:
CURL* m_curl;
};
By use of this, e.g.

CurlOpt::Verbose v(on);

I get a compiler error:

EasyCurl.cpp: In member function »void EasyCurl::setVerbose(bool)«:
EasyCurl.cpp:124: Fehler: keine passende Funktion für Aufruf von
CurlOption<bool, 41l>::CurlOption(bool&)«
EasyCurl.hpp:19: Anmerkung: Kandidaten sind: CurlOption<bool,
41l>::CurlOption()
EasyCurl.hpp:19: Anmerkung: CurlOption<bool, 41l>::CurlOption(const
CurlOption<bool, 41l>&)

Obviously the right ctor is missing. Anyway, do I have all the stuff
from the Template (typedefs including) to rewrite for the specialized
template class? Or is there another way? I thought I need only to
overwrite the specialized members - where is my mistake? Is there a
better and correct way?

Thanks
Olaf

Jul 24 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Olaf wrote:
[..] I have the following
classes:

template<typename T, long CURLOPT_ID>
class CurlOption: boost::noncopyable {
public:
typedef typename boost::call_traits<T>::param_type param_type;
....
public:
// constructors:
CurlOption() {}
CurlOption(param_type v) : m_value(v) {}

public:
long option() const { return CURLOPT_ID; }
result_type parameter() { return m_value; }
void setopt(CURL* handle);

private:
value_type m_value;
};

and the specialized for the templated arguments T (ether bool, long,
std::string etc.):

template<long CURLOPT_ID>
class CurlOption<bool, CURLOPT_ID{
public:
void setopt(CURL* handle) {
curl_easy_setopt(handle,
this->option(), this->value() ? 1 : 0);
}
};

e.g. used like

[.. some errors, with the message in German, I can't read German ..]

Obviously the right ctor is missing. Anyway, do I have all the stuff
from the Template (typedefs including) to rewrite for the specialized
template class?
Of course.
Or is there another way?
Not really.
I thought I need only to
overwrite the specialized members - where is my mistake?
Your mistake in thinking that a template specialisation contains all
stuff from the unspecialised one except the stuff you [re]define. It
does not.
Is there a
better and correct way?
Inheritance, maybe? You still can't inherit constructors, though.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 24 '07 #2

P: n/a
>I thought I need only to
>overwrite the specialized members - where is my mistake?

Your mistake in thinking that a template specialisation contains all
stuff from the unspecialised one except the stuff you [re]define. It
does not.
>Is there a
better and correct way?

Inheritance, maybe? You still can't inherit constructors, though.
Well, I solved the problem using traits (finally I have to write about 5
specialized templates). Attached the result. Maybe there are better
ways? Class Option must be copyable by use of a temporary for Verbose
(in main). Why? Maybe better solutions here?

Thanks
Olaf

#include <iostream>
#include <string>
#include <boost/utility.hpp>
#include <boost/call_traits.hpp>
using namespace std;

enum {
VERBOSE_ID,
FILE_ID
};

template<typename Tstruct OptionTraits : public boost::noncopyable { };

template<>
struct OptionTraits<bool: public boost::noncopyable
{
static long get(bool value) { return value; }
static std::string type() { return "bool"; }
};

template<>
struct OptionTraits<std::string: public boost::noncopyable
{
static const char* get(const std::string& value) {
return value.c_str();
}
static std::string type() { return "string"; }
};

template<typename T, long ID>
class Option // : public boost::noncopyable
{
public:
typedef typename boost::call_traits<T>::param_type param_type;
typedef T value_type;
typedef typename boost::call_traits<T>::value_type result_type;

public:
Option(param_type v) : m_value(v) {}

public:
long option() const { return ID; }
result_type parameter() { return m_value; }

public:
void setopt(int /*handle*/) const {
// work with handle; not relevant for problem here
// required is ID + value (and T bool,string etc. of course)
// for legacy API
cout << "option<"
<< OptionTraits<T>::type() << ", " << ID << ">: "
<< OptionTraits<T>::get(m_value) << "\n";
}
private:
value_type m_value;
};
typedef Option<bool, VERBOSE_ID> Verbose;
typedef Option<std::string, FILE_IDFile;
class Foo : boost::noncopyable
{
public:
Foo() : m_handle(0) {}

public:
void perform();

template<typename T, long ID>
void setopt(const Option<T, ID>& opt) {
opt.setopt(m_handle);
}
private:
int m_handle;
};

int main()
{
//Verbose v(true);
File f("bar.txt");

Foo foo;
foo.setopt(Verbose(true));
foo.setopt(f);
}
Jul 25 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.