954,498 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

template specialization for const T and dynamic argument deduction

Hi All,

Can you please help me to understand why the following code is behaving this way?
I think both outputs should be 1 ( 1 means const T), but its not!!

template <typename T>
struct IsConst{
	enum {isConst = 0};
};

template <typename T>
struct IsConst<const T>{
	enum {isConst = 1};
};

template <typename T>
void print(T val){
	cout << IsConst<T>::isConst << endl; //prints 0
}
int main() {

	const int x = 10;

	print(x); //why dynamic argument deduction deducting it as normal integer?

	cout << IsConst<const int>::isConst << endl; //prints 1

	return 0;
}


why dynamic argument deduction deducting it as normal integer?

Thanks in advance.

S.

learningcpp
Newbie Poster
17 posts since Nov 2010
Reputation Points: 18
Solved Threads: 0
 
why dynamic argument deduction deducting it as normal integer?


Top level CV qualifiers are stripped during the type deduction. That's actually expected behavior for template function parameters that aren't a pointer or reference.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

As Narue said, the top-level cv-qualifier is discarded in function calls. This is simply because, like in your example, when you pass-by-value, the top-level cv-qualifier of the original value doesn't and shouldn't matter, because it is copied to the function anyways.

To fix the problem, simply make the parameter to print() a reference to T instead of T, as so:

#include <iostream>

template <typename T>
struct IsConst{
	enum {isConst = 0};
};

template <typename T>
struct IsConst<const T>{
	enum {isConst = 1};
};

template <typename T>
void print(T& val){ //notice the & here.
	std::cout << IsConst<T>::isConst << std::endl; //prints 1.. hurray!!
}
int main() {

	const int x = 10;

	print(x); //x will be implicitly transformed to 'const int&'

	std::cout << IsConst<const int>::isConst << std::endl; //prints 1

	return 0;
}
mike_2000_17
Posting Virtuoso
Moderator
2,134 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
 

Thanks guys!!
It was helpful, I was looking in to boost code and found the solution.
But didn't know that const was getting stripped off.

learningcpp
Newbie Poster
17 posts since Nov 2010
Reputation Points: 18
Solved Threads: 0
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: