Thread: Compile time FizzBuzz error (C++11 / Templates / String Literals)

  1. #1
    Registered User inequity's Avatar
    Join Date
    Nov 2010
    Location
    Seattle, Washington
    Posts
    59

    Cool Compile time FizzBuzz error (C++11 / Templates / String Literals)

    So I was trying to write a compile time version of FizzBuzz, but I'm having a problem.
    And I can't seem to figure it out.

    It could be something really simple and stupid, but at this point I'm just kinda getting tunnel vision and could use some fresh eyes if anybody had a second.

    I'm compiling with GCC 4.6.1.

    Here is the code

    And this is the error (though it's recursive, so I'll just post a teensy-bit):
    Code:
    FizzBuzz.cpp: In instantiation of 'const char FizzBuzzMetaFunc<98u>::value [4]':
    FizzBuzz.cpp:39:92:   recursively instantiated from 'generate_array_impl<98u, FizzBuzzMetaFunc, ((const char*)(& FizzBuzzMetaFunc<99u>::value))>'
    FizzBuzz.cpp:39:92:   instantiated from 'generate_array_impl<99u, FizzBuzzMetaFunc>'
    FizzBuzz.cpp:51:63:   instantiated from 'GenerateArray<100u, FizzBuzzMetaFunc>'
    FizzBuzz.cpp:66:58:   instantiated from here
    FizzBuzz.cpp:61:12: error: invalid conversion from 'const char*' to 'char' [-fpermissive]
    This is kind of out there, so no big deal if I don't get any responses.
    I can't figure out if I'm doing something totally wrong with the literal strings, or what.

    If anybody maybe has GCC and likes this stuff, and want's to tell me how wrong I am, I'd appreciate it!

    I'm building it with
    Code:
    g++ FizzBuzz.cpp -o buzz.exe -std=c++0x -Wall -Wextra
    If not, thanks anyways! Have a nice day

    p.s. - My apologies if the code makes you think "what the hell was he thinking?". At this point, I'm not really sure either.

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    I'd slaughter another cockroach for those "The myth of FizzBuzz" and "Universities Dumping Graduates" links.

    *shrug*

    In any event, templates, `constexpr', and friends don't change the nature of C++; they extend it.

    Arrays still decay into pointers.
    Pointers do not carry size information.
    Arrays can not be copy-assigned from arrays.
    The compiler can not determine the size of an array by means of copy-assignment.
    Mechanics of templates are still largely immutable meaning a purely functional approach.

    I could go on, but I think you can see that your approach is entirely flawed.

    It can be done, and easily so, but you are going to have to find an approach to building the recursion without violating any of the above.

    Soma

  3. #3
    Registered User inequity's Avatar
    Join Date
    Nov 2010
    Location
    Seattle, Washington
    Posts
    59
    Thank you. Seeing it laid out like that makes things much more clear.

  4. #4
    Registered User inequity's Avatar
    Join Date
    Nov 2010
    Location
    Seattle, Washington
    Posts
    59
    Hey, just wanted to say I fixed it! Thanks for the help Soma

    For anybody who's interested: http://pastebin.com/6StzYjVw

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    I only took a casual glance, but from what I saw you need to fix your "ASCII" mathematics and can do away with the "C++11" requirements by mapping the character arrays as static variables.

    ^_^;

    For bonus points: can you do it so that a single

    Code:
    std::cout << A::gString << '\n';
    prints out the entire string (one value per line).

    Soma

  6. #6
    Registered User inequity's Avatar
    Join Date
    Nov 2010
    Location
    Seattle, Washington
    Posts
    59
    So I fixed it up a bunch, but I can't seem to get around needing the constexpr constructors to access those values.
    It complains that I can't use the values from a static array in a constant expressions. Specifically this code produces this error (a lot of times):

    Code:
    FizzBuzz.cpp: In instantiation of 'FizzBuzzChar<1u, 0u>':
    FizzBuzz.cpp:88:46:   instantiated from here
    FizzBuzz.cpp:56:8: error: the value of 'FBResult<'\000', 1u>::data' is not usable in a constant expression
    FizzBuzz.cpp:45:12: note: 'FBResult<'\000', 1u>::data' was not declared 'constexpr'
    FizzBuzz.cpp:56:8: error: enumerator value for 'value' is not an integer constant
    Plus I think I'd still be inside the C++11 requirements because I'd still need the variadic templates. But if you've got any idea what I'm doing wrong to get this error, or if it's just a standard thing, please inform me!

    Thanks again

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    *shrug*

    Apologies. I don't know what else to say. I simply missed the use of variadic templates because I didn't spend much time with the new code.

    I intended to offer two separate suggestions. (You can get rid of C++11 features and print out the results one line at a time. You can combine all the strings into one storage array and print that single string.) Of course, you can do my variation without C++11 features; it is simply extremely tedious and disturbingly ugly as `constexpr' and variadic templates are extremely useful for defining recursive facilities.

    I would not actually wish the C++98 version of my variation on anyone. I'm not joking. Doing it that way till not teach you anything new over doing both suggestions separately. Well, okay, doing it without C++11 features will teach you to cope with the limit offering templates supports of the "monads" concept. That support is so extremely limited I've never actually used it for anything real. It is actually easier to cope without using it at all.

    I'm not going to tell you how to do it; you will not learn anything from the exercise if I do making it even more of a pointless waste of your time. (It isn't even something that you could go "Look what I can do!".) I will give you a few crucial hints. You can't use a character array (even as extra unknown arguments) as a template parameter. You must assume that absolutely everything is a type because types are always constants. You must understand iteration as recursion.

    As for fixing what you have, I don't know what to say beyond "Your approach is wrong." if you are going to try without using C++11 features. Of course, if you are going to use C++11 features the suggestion would be "You need to employ `constexpr'." And further, if you return to your original approach (iteration of multiple arrays) you don't need the variadic templates.

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. compile time error
    By kapil1089thekin in forum C++ Programming
    Replies: 4
    Last Post: 09-01-2010, 12:29 PM
  2. Length of string at compile time?
    By TriKri in forum C Programming
    Replies: 14
    Last Post: 05-23-2010, 11:16 AM
  3. compile time error or runtime error?
    By George2 in forum C# Programming
    Replies: 3
    Last Post: 05-07-2008, 07:08 AM
  4. Compile time error
    By j_spinto in forum C Programming
    Replies: 31
    Last Post: 05-06-2005, 10:41 AM
  5. compile time error...
    By Ruchikar in forum C++ Programming
    Replies: 7
    Last Post: 07-09-2002, 02:51 AM

Tags for this Thread