Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
285 views
in Technique[技术] by (71.8m points)

c++ - How do I restrict a template class to certain built-in types?

This issue has been discussed a few times but all the solutions I have found either didn't work or were based on boost's static assert. My problem is simple. I have a class, and I only want to allow real types (double and float). I want a compile-time error if I try to instantiate the class with a type other than float or double. I am using Visual C++ 11. Here is what I have tried:

template <typename RealType>
class A
{
  // Warning C4346
  static_assert(std::is_same<RealType, double>::value || std::is_same<RealType, float>::value);
}


template <typename RealType>
class A
{
  // Error C2062: type 'unknown' unexpected
  static_assert(decltype(RealType) == double || decltype(RealType) == float);
}

Any ideas? Thanks in advance!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In your first example, static_assert should take a second parameter which would be a string literal, otherwise it's deemed to fail (edit: dropping the the second parameter is legal since C++17). And this second argument cannot be defaulted.

Your second example is incorrect for several reasons:

  • decltype is meant to be used on an expression, not on a type.
  • You simply cannot compare types with ==, the correct way to do this is what you try in your first attempt with std::is_same.

So, the right way to do what you are trying to achieve is:

#include <type_traits>

template <typename RealType>
class A
{
  static_assert(std::is_same<RealType, double>::value || std::is_same<RealType, float>::value,
                "some meaningful error message");
};

Moreover, I bet you are trying to constrict your template to floating points values. In order to do this, you can use the trait std::is_floating_point:

#include <type_traits>

template <typename RealType>
class A
{
  static_assert(std::is_floating_point<RealType>::value,
                "class A can only be instantiated with floating point types");
};

And as a bonus, take this online example.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...