Reputation: 2824
How does one specialize a template function to generate an error at compile-time if a user attempts to call said function with a given template parameter?
I was able to get this behavior for a template class by using the following idiom...
template <typename T>
class MyClass< std::vector<T> >;
The basic signature of the function which I am trying to modify is...
template <typename T>
T bar(const int arg) const {
...
}
If I use the same paradigm that I used to disallow certain template classes...
template<>
std::string foo::bar(const int arg) const;
I can generate a linker error, which I suppose is more desirable than a runtime error, but still not really what I'm looking for.
Since I am not able to use C++11, I cannot use static_assert
, as described here. Instead, I am trying to use BOOST_STATIC_ASSERT
like so...
template<>
std::string foo::bar(const int arg) const {
BOOST_STATIC_ASSERT(false);
return "";
}
However, this generates the following compile-time error, even when I am not trying to call an instance of the function with the template parameter I am attempting to disallow...
error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
I found this post, but it doesn't really offer any insight that I feel applies to me. Can anyone help?
Upvotes: 1
Views: 454
Reputation: 53
It seems C++ don't allow specialize template member function. So if you want to use same interface, you should use other technology. I'd like to use trait_type to implement this.
template <class T>
struct is_string : false_type {};
template <>
struct is_string<string> : true_type {};
template <typename T>
class MyClass {
private:
T bar(const int arg, false_type) const {
return T();
}
std::string bar(const int arg, true_type) const {
return "123";
}
public:
T bar(const int arg) const {
return bar(arg, is_string<T>());
}
};
If you can not use C++11, you must implement false_type and true_type yourself. Or you can use specialize template class.
Upvotes: 2
Reputation: 109119
Use boost::is_same
to generate a compile-time boolean value that can then be used with BOOST_STATIC_ASSERT
to perform the check.
template <typename T>
T bar(const int)
{
BOOST_STATIC_ASSERT_MSG((!boost::is_same<T, std::string>::value),
"T cannot be std::string");
return T();
}
bar<int>(10);
bar<std::string>(10); // fails static assertion
Upvotes: 5