Its only partial because gcc doesn't seem to like it otherwise nor does it seem to be allowed in the ISO standard, although I have a vague memory it used to work in MSVC..
Anyway, this gives me 0 (false) when its suppose to use the specialization - if I replace H with int in the specialization it works, but that would defeat the point.
int main(){
cout << c<int>::h<int>::val<<endl;
return 0;
}
Anyone know what the problem is, or know any workarounds? Does it work in MSVC (I recall you can't initialize the static constants in msvc inside the struct but have to do it outside, but my guess that was non standard) or any other compiler than gcc? Is it suppose to work (give 1) according to the ISO standard?
Last edited by kedaman; Apr 3rd, 2007 at 08:06 AM.
Reason: code formatting
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
Nonetheless, it would be interesting to know if this is a standard incompliance in gcc and if other compilers can do it.
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
Well that is certainly interesting. Maybe its just gcc that is at fault. I'd be happy to know if DevCPP is capable of it. Thanks.
BTW, if you remove the T paramteres, will it compile?
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
What compiler arguments are you using? I know GCC (g++) has the ability to specify what compliance you use.
I just tried the following command line on your first code sample and it compiled without complaint (I'm running under Linux with default library setup)... g++ kedaman.cpp -o kedaman -ansi -pedantic
But, of course, it returns the wrong value.
Does this have something to do with integers being value types and classes being ref types?
I'm only compiling with -fpermissive, but thats only because I haven't figured out how to fix this strange error yet:
Code:
rms.cpp: In member function ‘void sys<T>::tkonvos()’:
rms.cpp:248: error: there are no arguments to ‘subsys_tkonvo’ that depend on a template parameter, so a declaration of ‘subsys_tkonvo’ must be available
rms.cpp:248: error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
Of course it should compile, but just gives the wrong value. Now I wonder whether its gcc or msvc which has got it wrong according to the standard that is.
Does this have something to do with integers being value types and classes being ref types?
Not sure what you mean there, but the point was that it should deduce that H = int, since it is using c<int> there.
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
Also... is it at all possible to make template specializations for member functions in template classes? I don't seem to be able to do either partial or explicit specializations in gcc.
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
Also... is it at all possible to make template specializations for member functions in template classes? I don't seem to be able to do either partial or explicit specializations in gcc.
What version of gcc are you using?
I was able to do this under gcc 4.1.2:
Code:
#include <iostream>
template <class T>
class c
{
public:
int foo() { return 0; }
};
// foo returns 1 if [T = int]
template<>
int c<int>::foo() { return 1; }
int main()
{
c<int> x;
c<float> y;
std::cout << x.foo() << std::endl;
std::cout << y.foo() << std::endl;
return 0;
}
The trick is that specializations must be made outside of the class declaration.
Every passing hour brings the Solar System forty-three thousand miles closer to Globular Cluster M13 in Hercules -- and still there are some misfits who insist that there is no such thing as progress.
I don´t have access to my machine at the moment but I don´t think the version is particularly old. It came with the latest ubuntu distribution i downloaded a couple of months ago. You are not really doing what I was trying to do though. I had no problem with unnested explicit specializations and nested partial specializations of classes, but the problem is extremely annoying with nested specializations, that is of template member functions (perhaps they may work in non template classes, but as such they would be useless to me)
Try doing a template <class X> int foo() and a template <> foo<int>()
also try template <class X,class Y> int foo2() and template <class X> int foo2<int>()
Thanks for trying to be helpful though.
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
I forgot I got my live cd with me, it appears I have 4.1
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
struct c{
template <class X> int foo(){return 0;}
template <> int foo<int>(){return 1;}
};
gives
test.cpp:11: error: explicit specialization in non-namespace scope ‘struct c’
test.cpp:11: error: template-id ‘foo<int>’ for ‘int foo()’ does not match any template declaration
test.cpp:11: error: invalid function declaration
PHP Code:
struct c{
template <class X,class V> int foo(){return 0;}
template <class V> int foo<int,V>(){return 1;}
};
test.cpp:11: error: function template partial specialization ‘foo<int, V>’ is not allowed
I know there is a workaround, namely to use nested template structs, but it is highly annoying to do every time not to mention I have to pass the this pointer around in those. Does it work with other compilers and is this forbidden by the standard?
edit: This is so unbelievably annoying, I cant even use partial specialization of functions outside c.
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
Partial specialization of functions is disallowed by the standard, for unknown reasons. Possibly the reason is that the implementability of the feature was in question - there are several specific bans in the standard that are there only because the committee wasn't sure if the feature could be implemented with reasonable effort. It's always easier to add to the standard than remove from it.
Hmm.. garbage collection... are they going to turn C++ into java? Concepts looks really nice - especially concept based overloading. This way you can do various things on different sets of types that has specific type traits without having to do template specializing every type separately. Then there are some things called axioms, that looks way problematic to implement:
Code:
axiom Associativity(Op op, T x, T y, T z) {
op(x, op(y, z)) == op(op(x, y), z);
}
How is it suppose to prove that any functor Op is associative at compiletime? If partial specialization of functions are disallowed because they can't be implemented with reasonable effort, I do wonder how this is going to be implemented in any easy way.
Anyways, thanks CB, when is this suppose to come out?
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
They hope they can manage it in 2009, hence the name change from C++0x to C++09.
Axioms don't need to be proved by the compiler. If it can, all the better; if not, you better make sure you're right or suffer the consequences - the compiler is allowed to optimize based on the axiom. E.g.