template class with default value

Hi,

Please refer to the code below, the attribute class is created with the value type and default value, but why it doesn't work for std::string?

Thanks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <string>
#include <iostream>
using namespace std;


template<typename value_t, typename value_t value = value_t()>
struct attribute {
	value_t val;

	attribute() : val(value) {}
};

int main() {
	attribute<long, 1> style; // ok
	attribute<long> ex_style; // ok

	attribute<string> title; // error

}
1
2
3
4
5
6
template < typename T > struct attribute 
{
    T val;

    explicit attribute( const T& value = T() ) : val(value) {}
};

template < typename T > struct attribute
{
T val;

explicit attribute( const T& value = T() ) : val(value) {}
};


Sorry I didn't explain the question clearly, the class attribute should be able to take different default values. because a window's default style maybe WS_VISIBLE, ex_style may be 0, they are both of type long, then I could create these two attributes like
1
2
3
4
struct window {
	attribute<long, WS_VISIBLE> style; 
	attribute<long> ex_style; 
};
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
— integral or enumeration type,
— pointer to object or pointer to function,
— lvalue reference to object or lvalue reference to function,
— pointer to member,
— std::nullptr_t.
- IS

C++11:
1
2
3
4
5
6
7
8
9
10
11
12
13
template < typename T > struct attribute
{
    T val;

    explicit attribute( const T& value = T() ) : val(value) {}
};

struct window
{
    attribute<long> style { WS_VISIBLE } ;
    attribute<long> ex_style ;
    attribute<std::string> title { "Hello World!" } ;
};


C++98: Specialize for std::string etc. Or use Boost's type_traits and enable_if.
@JLBorges
1. how is the char const * implicitly converted to a std::string when the constructor is explicit?
2. Why would you need to specialize for std::string in C++03?
Thanks JLBorges,
attribute<long> style { WS_VISIBLE } ;
I've never seen this c++11 syntax before.
> 1. how is the char const * implicitly converted to a std::string when the constructor is explicit?

attribute<std::string> title { "Hello World!" } ; is initialization;
equivalernt to attribute<std::string> title ( "Hello World!" ) ;

attribute<std::string> title = "Hello World!" ; would be an error because the constructor is explicit.


> 2. Why would you need to specialize for std::string in C++03?

A std::string is not allowed as a non-type template-parameter.


> I've never seen this c++11 syntax before.

It uses two language features introduced in C++11
a. In-class member initializers: http://www.stroustrup.com/C++11FAQ.html#member-init
b. Uniform initialization: http://www.stroustrup.com/C++11FAQ.html#uniform-init
JLBorges wrote:
A std::string is not allowed as a non-type template-parameter.
Where are you using a non-type template parameter?
The non-type parameter was there in the original code:
1
2
3
template<typename value_t, /*typename*/ value_t value = value_t()>
struct attribute {
// ...  


because this would be handy if there were no in-class member initializers:
1
2
3
struct window {
	attribute<long, WS_VISIBLE> style; 
        ...
Ah, I thought you were referring to the C++11 version; my mistake.
Topic archived. No new replies allowed.