尝试实例化bitset并获取“非类型模板参数不是常量表达式”

时间:2018-06-04 20:14:40

标签: c++ templates

在我的main函数中,我有以下代码块。特别是,带注释的行给出了以下错误

非类型模板参数不是常量表达式     bitset \< LSB> b = make_token_triple \< L,S,B,LSB>(t);

我手边不会知道B的价值。如何在不收到上述错误的情况下实例化make_token_triple?

const size_t S = 3, L = 4;
tokenTriple t = tokenTriple(S,"cat");
t.updateTriple("s");
const size_t B = t.calcBytesNeeded();
const size_t LSB = L + S + B;
bitset<LSB> b =  make_token_triple<L,S,B,LSB>(t);        //Gives error
cout << b << endl;

这是make_token_triple

的定义
template <size_t L, size_t S, size_t B, size_t LSB>
std::bitset<LSB> make_token_triple(tokenTriple token_triple)
{
    std::bitset<L> L_bset;
    std::bitset<S> S_bset(token_triple.getString().length());  
    std::bitset<B> str_bset = str_to_bset<B>(token_triple.getString());
    return join3<L,S,B,LSB>(L_bset,S_bset,str_bset);

}

这里是头文件令牌Tripple

        #ifndef TOKENTRIPLE_HPP
        #define TOKENTRIPLE_HPP
        #include <string>

        class tokenTriple {
            private:
                //@:set to 2^(S) - 1
                //@:denotes max str size in triple
                size_t max_strlen;

                //@: the current string
                std::string str;
            public:
                //@:a string to add to the triples string
                //#:concatenate s onto the end of str
                tokenTriple(size_t S,std::string s);

                //@:s is the string to potentially concatenate
                //@: onto str        
                //#:If there is enough room for s, then add it
                //#:to the end of str
                void updateTriple(std::string s);

                //#return the number of bytes needed to store str
                size_t calcBytesNeeded() ;

                ////////////////////// 
                //SECTION: Get Methods
                ////////////////////// 

                std::string getString();
                size_t getMaxStrLength();

                /////////////////////////////
                //SECTION: True/False Methods
                /////////////////////////////

                //#: if no more characters can be added to str
                //#: returns true
                bool hasCapacity(std::string s);
        };

        #endif //TOKENTRIPLE_HPP

这里是来自token_triple的.cpp

    #include "token_triple.hpp" 
    #include <math.h>
    #include <iostream>

    tokenTriple::tokenTriple(size_t S,std::string s)
        : str(s)
    {
        max_strlen = pow(2,S) - 1;
    }

    void tokenTriple::updateTriple(std::string s)
    {
        //TODO: change this to standard error
        if (! hasCapacity(s)){
            std::cout << "tried to add string without enough capacity" \
                << std::endl;
            return;
        }
        str += s;
    }

        size_t tokenTriple::calcBytesNeeded() {
        return 8 * str.length();
    }

    //SECTION: Get Methods
    std::string tokenTriple::getString()
    {
        return str;
    }

    size_t tokenTriple::getMaxStrLength(){
        return max_strlen;
    }

    //SECTION: True/False Methods
    bool tokenTriple::hasCapacity(std::string s){
        if (s.length() + str.length() < max_strlen)
            return true;
        else
            return false;
    }

最后这里是bit_tools的.hpp文件,其中make_token_triple在底部定义。请注意,由于所有模板

,我没有accmopnaning .cpp文件
//TODO: implement a read function that takes a binary string
//and reads the characters. 

//bit_tools.hpp
//Because of the use of template funciton
//I have put definitions in .h

#ifndef bittools_hpp
#define bittools_hpp

#include <bitset>
#include <ostream>
#include <vector>
#include <string>
#include "token_triple.hpp"

//@:bset is the bitset to be slicesk
//@:L is is the starting left most index
//@:U is the ending right most index
//#: returns a subset of the bitset between [i,j]
template<size_t sizeA,size_t sizeB>
std::bitset<sizeA> slice(std::bitset<sizeB> bset,\
                         unsigned int L, unsigned int U)
{
    if (U-L+1 != sizeA){
        throw("Error in slice, incorrect slice size");
    }

    std::bitset<sizeA> new_bset;
    unsigned int new_bset_index = 0;
    for (int i = L; i <= U; ++i){
        new_bset[new_bset_index] = bset[i];
        new_bset_index++;
    }
    return new_bset;
}

//@:bset is a binary str of 8 bits long
//#:convert bset into its character representation 
char bset_to_chr(std::bitset<8> bstr){
    return bstr.to_ulong();
}



//@:chr is a character literal
//#:convert chr to its 8 bit binary representation
std::bitset<8> chr_to_bset(char chr){
    return std::bitset<8>(chr);
}

//@:sizeA specifies the size of the bitset being copied into
//@:bset is the bitset being copied into
//@:c is the character that will be copied into bset
//@:index tells us where to start copying c into, we proceed
//@: from there to the next 7 higher indices
//#: copy c into bset starting at index and moving to righ
template<size_t size>
void copy_char(std::bitset<size>& bset, char c, size_t index)
{
    std::bitset<8> chr = chr_to_bset(c);
    size_t U = index + 7, chr_index = 0;
    for (; index <= U; ++index){
        bset[index] = chr[chr_index++];
    }
}

//@:size will be how large bset will be
//@: size will always be 8*strleng
//@:str is the string being converted to a bset
//#: result is a binary representation of the string
//#: note that the string will be stored in what is
//#:equiv of left to right. so cat is stored as
//#:[binary(t),binary(a),binary(c)]
template<size_t size>
std::bitset<size> str_to_bset(std::string str)
{
    std::bitset<size> bset;
    size_t i = 0, str_index = 0;
    for ( ; i < size; i+= 8){
        copy_char<size>(bset,str[str_index++],i);
    }
    return bset;
}


//@:bset is a 16 bit binary set representing an index into search buf
//#:convert bset into its intger representation
unsigned int bset_to_int(std::bitset<16> bset){
    return bset.to_ulong();
}

//Implicit Parameters
//@:sizeJoin the size of the joined bit set
//@:sizeA the size of bitsetA
//@:sizeB the size of bitset B
//Paramaters
//@:bsetA
//@:bsetB
//#: returns a new bitset where bsetB is appened
//#: to the end of bsetA 
template <size_t sizeA, size_t sizeB, size_t sizeAB>
std::bitset<sizeAB> join2(std::bitset<sizeA> bsetA, std::bitset<sizeB> bsetB){
    return std::bitset<sizeAB>(bsetA.to_string() + bsetB.to_string());
}

//Implicit Parameters
//@:sizeA,sizeB,sizeC,sizeABC 
//Paramaters
//@:bsetA,bsetB,bsetC
//#: returns new bset of the form bsetA bsetB bsetC
//#: no spaces in between. New bitset as size A + B + C
template <size_t sizeA, size_t sizeB,size_t sizeC,size_t sizeABC>
std::bitset<sizeABC> join3(std::bitset<sizeA> bsetA,\
                           std::bitset<sizeB> bsetB,\
                           std::bitset<sizeC> bsetC)
{
    return std::bitset<sizeABC>(bsetA.to_string() + \
                                bsetB.to_string() + \
                                bsetC.to_string());
}

//@: A is bitset 
//@: B is bitset 
//@: bset is a bitset of sizeAB that will be split
//#:sizeA highest bit of bset copied into A
//#:sizeB low bits copied into B
template <size_t sizeA, size_t sizeB, size_t sizeAB>
void split2(std::bitset<sizeA>& A,\
            std::bitset<sizeB>& B,
            std::bitset<sizeAB> bset)
{
    size_t L,U;
    //Set B indices
    L = 0; U = sizeB - 1;
    B = slice<sizeB,sizeAB>(bset,L,U);
    //Set A indices
    L = U + 1; U = L + sizeA - 1;
    A = slice<sizeA,sizeAB>(bset,L,U);
}

//Paramaters
//@: A,B,C are all bit sets
//@: bset is a bitset of sizeABC that will be split
//#:copies A high order bits and stores in A
//#:copies next highest remaining sizeB bits stores in B
//#:copies reamining low order bits and stores in C
//#:In effect bset is split into three new bit sets
template <size_t sizeA, size_t sizeB, size_t sizeC, size_t sizeABC>
void split3(std::bitset<sizeA>& A,\
            std::bitset<sizeB>& B,\
            std::bitset<sizeC>& C,\
            std::bitset<sizeABC> bset)
{
    size_t L,U;
    //Set C indices
    L = 0; U = sizeC - 1;
    C = slice<sizeC,sizeABC>(bset,L,U);
    //Set B indices
    L = U + 1; U = L + sizeB - 1;
    B = slice<sizeB,sizeABC>(bset,L,U);
    //Set A indices
    L = U + 1; U = L + sizeA - 1;
    A = slice<sizeA,sizeABC>(bset,L,U);
}


//Paramaters L,S are implicit. They are passed into size as a sum
//@:L is nuumber of bits to use in the encoding of (0)
//@:S is number of bits to use in encoding (0)
//#:produces a special pair (0,0) which denotes the end of file
//#:the binary str produced will be of length L + S
template <size_t sizeLS>
std::bitset<sizeLS> encode_eof()
{
   return std::bitset<sizeLS>();

}

//Paramaets N,L are implicit. They are passed into size
//@:L number of bits to use in encoding match
//@:match is int specifying length of the match
//@:N number of bits to use in encoding offset
//@:offset is int specifying offset into the window
//@: with respect to current window configuration
//#: return N + L bit binary string of emulating (len,offset)
//#: recall that if matchlen = i then binary string to represnt i
//#: will be actually representing i-1. If matchlen = 2 then 0001 would be
//#: the representation
template <size_t L,size_t N, size_t LN>
std::bitset<LN> make_token_double( \
                                    size_t matchlen,\
                                    size_t offsetindex)
{
    std::bitset<LN> bset;
    std::bitset<L> Lset(matchlen);
    std::bitset<N> Nset(offsetindex - 1);
    bset = join2<L,N,LN>(Lset,Nset);
    return bset;
}

//@:L is number of bits to use when encoding mathc (note L is going to be 0 here)
//@:S is number of bits to use to encode length of str literal
//@:B is the number of bytes required to represent the string
//@:LSB is the sum of L S B (the total bits needed for the bitset)
//@:token_triple is a tokenTriple that holds the data neccessary
//@:    to construct a token triple
//#:encodes a triple of the form (code,strlen,chars) pair
//#: get a L + S + len(str) binary/char str 
//Assume: that token_triple holds a valid string
template <size_t L, size_t S, size_t B, size_t LSB>
std::bitset<LSB> make_token_triple(tokenTriple token_triple)
{
    std::bitset<L> L_bset;
    std::bitset<S> S_bset(token_triple.getString().length());  
    std::bitset<B> str_bset = str_to_bset<B>(token_triple.getString());
    return join3<L,S,B,LSB>(L_bset,S_bset,str_bset);

}

#endif //

0 个答案:

没有答案