C++ 使用;constexpr“;为模板参数使用字符串文字

C++ 使用;constexpr“;为模板参数使用字符串文字,c++,templates,c++11,string-literals,constexpr,C++,Templates,C++11,String Literals,Constexpr,我已经编写了一些代码,通过使用constexpr将const char*转换为int,因此我可以使用const char*作为模板参数。代码如下: #include <iostream> class conststr { public: template<std::size_t N> constexpr conststr(const char(&STR)[N]) :string(STR), size(N-1

我已经编写了一些代码,通过使用
constexpr
const char*
转换为
int
,因此我可以使用
const char*
作为模板参数。代码如下:

#include <iostream>

class conststr
{
    public:
        template<std::size_t N>
        constexpr conststr(const char(&STR)[N])
        :string(STR), size(N-1)
        {}

        constexpr conststr(const char* STR, std::size_t N)
        :string(STR), size(N)
        {}

        constexpr char operator[](std::size_t n)
        {
            return n < size ? string[n] : 0;
        }

        constexpr std::size_t get_size()
        {
            return size;
        }

        constexpr const char* get_string()
        {
            return string;
        }

        //This method is related with Fowler–Noll–Vo hash function
        constexpr unsigned hash(int n=0, unsigned h=2166136261)
        {
            return n == size ? h : hash(n+1,(h * 16777619) ^ (string[n]));
        }

    private:
        const char* string;
        std::size_t size;
};

// output function that requires a compile-time constant, for testing
template<int N> struct OUT
{
    OUT() { std::cout << N << '\n'; }
};

int constexpr operator "" _const(const char* str, size_t sz)
{
    return conststr(str,sz).hash();
}

int main()
{
    OUT<"A dummy string"_const> out;
    OUT<"A very long template parameter as a const char*"_const> out2;
}
#包括
类conststr
{
公众:
模板
constexpr conststr(const char(&STR)[N])
:字符串(STR),大小(N-1)
{}
constexpr conststr(const char*STR,std::size\u t N)
:字符串(STR),大小(N)
{}
constexpr字符运算符[](std::size\u t n)
{
返回nOUT(){std::cout虽然您的方法非常有趣,但它实际上并不是一种将字符串文本作为模板参数传递的方法。事实上,它是一个基于字符串文本的模板参数生成器,这是不一样的:您无法从
哈希字符串
中检索
字符串
。它有点挫败了字符串文本的全部兴趣模板中的随机变量

编辑:当使用的散列是字母的加权和时,以下是正确的,而编辑OP后则不是这样

正如mitchnull的回答所述,您的方法也可能存在问题。这可能是您的方法的另一个大问题,即碰撞。例如:

// Both outputs 3721
OUT<"0 silent"_const> out;
OUT<"7 listen"_const> out2;
然后,我通过类型参数传递“伪字符串文字”:

template<typename str>
struct out
{
    out()
    {
        std::cout << str::asString() << "\n";
    }
};
模板
构造出
{
out()
{

std::cout这是我用于模板常量字符串参数的模式。

F类{
静态constexpr const char conststr[]=“一些常量字符串”;
模板对象实例;
};

见:

Synxis,我编辑了我的代码。我的哈希函数是一个不专业的函数,现在它使用的是Fowler–Noll–Vo哈希函数。我相信这个函数没有同样的问题。我无法理解你的第一段关于“hashed_string”中的“string”?你没有将字符串传递给
输出,但
的结果是h()
。我认为你不能将这个值转换成字符串……因此,你不能让
输出你在括号之间写的字符串。哦,我明白了。事实上,这对我来说不是问题(当然你的观点是正确的)因为我想让模板像这样工作:假设我们有一个名为Integer的模板,Integer将与Integer不同,我将专门指定我的模板来执行此操作。你可以使用标记。我将在我的答案中使用它。好的观点。我更喜欢标记,因为它更“美观”你也可以选择不同的文字名称,例如
\u tag
。如果我的答案“解决”了你的问题,你可以将其标记为接受?否则,你可以(再次)评论它!哦,对不起,我总是忘了这么做:)
template<typename str>
struct out
{
    out()
    {
        std::cout << str::asString() << "\n";
    }
};
// tags
struct myTag {};
struct Long {};
struct Float {};

// class template
template<typename tag>
struct Integer
{
    // ...
};
template<> struct Integer<Long> { /* ... */ };

// use
Integer<Long> ...;  // those are 2
Integer<Float> ...; // different types