1

I am using boost 1.45.0 and have some code that does the following:

template <typename T = some_type, std::size_t N = 3> class my_class {
    public:
typedef T value_type;
        ...
        ...
        my_class(value_type i0) {BOOST_STATIC_ASSERT(N==1); m_data[0]=i0;}
    protected:
T m_data[N]; 
            //!< The internal data array used to store indices
}

This generates the following error on MS VC++ 2010 (which I understand has implemented static_assert as one of their major changes) and no errors on MS VC++ 2008:

 error C2338: N==1

Likewise, there are other errors at some other BOOST_STATIC_ASSERTs in the same code (left out for brevity).

I also tried replacing with the static_assert from VC++ but get a similar build error (prints out the message string).

What workaround exists for this?

p.campbell
  • 98,673
  • 67
  • 256
  • 322
squashed.bugaboo
  • 1,338
  • 2
  • 20
  • 36
  • What's the code that instantiates `func` that should trigger the error? – K-ballo Nov 01 '11 at 22:14
  • 5
    Well, `N` doesn't equal 1, so what do you expect? – GManNickG Nov 01 '11 at 22:22
  • `static_assert` fails when the condition is *false*, not when it is true. Maybe that's where your confusion comes from? Just to be clear, `3==1` is false, hence it fails. – fredoverflow Nov 01 '11 at 22:27
  • thanks @GMan: I see your point; but somehow I feel there might be a fix to this. Isn't this type of usage covered by SFINAE? Plus it builds fine on MS VC++ 2008 (albeit I was using boost 1.39.0 then) – squashed.bugaboo Nov 01 '11 at 22:31
  • The static assert is doing what it should be. You're checking that N == 1, but you set its default value to 3. So if any my_class instance with a default template paramater comes along, it should trigger that assertion. What are you trying to do? –  Nov 01 '11 at 22:34
  • From his code you can't tell what N is. You just assumed he leaves that parameter as default. – andriej Apr 03 '12 at 14:49

1 Answers1

2

I think you may be misunderstanding the purpose of static assertions. Static assertions are meant to state properties that must be true for the code to compile. If what you want is to write a function that won't be generated unless some condition is true but not fail compilation, you need to use SFINAE.

// don't forget to #include <type_traits> for std::enable_if

template <std::size_t N1 = N>
my_class(value_type i0, typename std::enable_if<N1==1>::type* = 0)
{m_data[0]=i0;}
Community
  • 1
  • 1
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • @Fernandes.. you might be on to something. Let me try this and get back with you. I think you nailed it. – squashed.bugaboo Nov 01 '11 at 22:34
  • @Fernandes, I tried this out but now I am getting a build error: error C2039: 'type' : is not a member of 'std::tr1::enable_if<_Test>' – squashed.bugaboo Nov 01 '11 at 22:47
  • @user545591 : That's what happens if N != 1 and you have no alternative constructor overloads to call. I.e., the whole purpose is to make the overload containing the `enable_if` ineligible during overload resolution if the condition is false, so you need some other overload to call in that circumstance. – ildjarn Nov 01 '11 at 22:57
  • Oh, right, I forgot something. Seems like you need to make the constructor a template for this to work. I'll edit. – R. Martinho Fernandes Nov 01 '11 at 22:59
  • @ildjarn: I do have other overloads. Just haven't listed them there. There's a constructor that takes 2 arguments and then 3 as well as one that takes none. So if N != 1, are you saying that the compiler should give the error above your comment? – squashed.bugaboo Nov 01 '11 at 22:59
  • @user545591 : You need another _eligible_ overload (at a minimum, one that has the same effective arity); otherwise, yes, the error you posted in the comment is absolutely expected. – ildjarn Nov 01 '11 at 23:01
  • 1
    @R.MartinhoFernandes : He's using VC++ 2010, which does not support default function template arguments, so your code as-is won't work. – ildjarn Nov 01 '11 at 23:02
  • @Fernandes: Now I run into another error essentially as ildjarn describes: error C4519: default template arguments are only allowed on a class template – squashed.bugaboo Nov 01 '11 at 23:05
  • @Fernandes & all: No problem, thanks all. Learnt something new after all. – squashed.bugaboo Nov 01 '11 at 23:07