gpt4 book ai didi

c++11 - 使用 c++11 标准中的 constexpr 错误还是我发现了一些编译器错误?

转载 作者:行者123 更新时间:2023-12-05 00:26:09 27 4
gpt4 key购买 nike

我正在使用 constexpr 关键字并编写了以下简单程序:

#include <iostream>

using namespace std;

template<typename T>
constexpr bool is_equal(T const* array1, T const* array2, size_t len)
{
return array1 == array2 || (len ? array1[len - 1] == array2[len - 1] && is_equal<T>(array1, array2, len - 1) : true);
}

template<typename T, size_t N1, size_t N2>
constexpr bool is_equal(T const (&array1)[N1], T const (&array2)[N2])
{
return N1 == N2 && is_equal<T>(array1, array2, N1);
}



template<typename T, size_t N>
constexpr size_t arraylength(T const (&array)[N])
{
return N;
}



constexpr size_t stringlength(char const* str, size_t len=0)
{
return str ? (*str ? stringlength(str + 1, len + 1) : len) : 0;
}



constexpr size_t min(size_t one, size_t another)
{
return one < another ? one : another;
}



constexpr size_t min_length(char const* str1, char const* str2)
{
return min(stringlength(str1), stringlength(str2));
}



template<typename T, size_t N1, size_t N2>
constexpr size_t min_length(T const (&array1)[N1], T const (&array2)[N2])
{
return min(N1, N2);
}



template<bool cond=false>
struct to_num
{
enum {value=0};
};

template<>
struct to_num<true>
{
enum {value=42};
};



template<size_t init>
struct two_times
{
enum {value=init*2};
};



static constexpr char x[]{"One string"};
static constexpr char y[]{"One string"};

static constexpr int a[]{1,2,3,4};
static constexpr int b[]{1,2,3,4};

static constexpr int const* const c = &a[0];
static constexpr int const* const d = &b[0];

int main()
{
cout << "The two literals are equal: " << to_num< is_equal("One string", "One string") >::value << endl; // COMPILES AND WORKS IN GCC BUT NOT IN CLANG
cout << "The two variables x & y are equal: " << to_num< is_equal(x, y) >::value << endl;
cout << "Pointers a & c are equal: " << to_num< a == c >::value << endl;
cout << "Pointers b & c are equal: " << to_num< b == c >::value << endl;
cout << "Pointers c & d are equal: " << to_num< c == d >::value << endl;
cout << "The contents of c & d is the same: " << to_num< is_equal(c, d, arraylength(a)) >::value << endl;
cout << "Pointers a & b are equal: " << to_num< a == b >::value << endl;
cout << "The contents of a & b is the same: " << to_num< is_equal(a, b) >::value << endl;
cout << "String x contains " << two_times< stringlength(x) >::value / 2 << " characters" << endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
cout << "String literal contains " << two_times< stringlength("literal") >::value / 2 << " characters" << endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
cout << "Array literal contains " << two_times< arraylength("literal") >::value / 2 << " values" << endl;
return 0;
}

正如评论所说,一些代码可以编译并与 g++ 一起工作,但不能与 clang++ 和其他编译和工作与 clang++ 一起工作,但不能与 g++

gcc 错误是:
comaprison.cpp: In function ‘int main()’:
comaprison.cpp:97:62: in constexpr expansion of ‘stringlength(((const char*)(& x)), 0ul)’
comaprison.cpp:29:55: in constexpr expansion of ‘stringlength((str + 1u), (len + 1ul))’
comaprison.cpp:97:64: error: ‘((((const char*)(& x)) + 1u) != 0u)’ is not a constant expression
cout << "String x contains " << two_times< stringlength(x) >::value / 2 << " characters" << endl;
^
comaprison.cpp:97:64: note: in template argument for type ‘long unsigned int’
comaprison.cpp:98:76: in constexpr expansion of ‘stringlength(((const char*)"literal"), 0ul)’
comaprison.cpp:29:55: in constexpr expansion of ‘stringlength((str + 1u), (len + 1ul))’
comaprison.cpp:98:78: error: ‘((((const char*)"literal") + 1u) != 0u)’ is not a constant expression
cout << "String literal contains " << two_times< stringlength("literal") >::value / 2 << " characters" << endl; // COMPILES AND WORKS IN CLANG BUT NOT IN GCC
^
comaprison.cpp:98:78: note: in template argument for type ‘long unsigned int’

和 clang++ 之一是:
comaprison.cpp:89:55: error: non-type template argument is not a constant expression
cout << "The two literals are equal: " << to_num< is_equal("One string", "One string") >::value << ...
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
comaprison.cpp:8:19: note: subexpression not valid in a constant expression
return array1 == array2 || (len ? array1[len - 1] == array2[len - 1] && is_equal<T>(array1, array2...
^
comaprison.cpp:14:24: note: in call to 'is_equal(&"One string"[0], &"One string"[0], 11)'
return N1 == N2 && is_equal<T>(array1, array2, N1);
^
comaprison.cpp:89:55: note: in call to 'is_equal("One string", "One string")'
cout << "The two literals are equal: " << to_num< is_equal("One string", "One string") >::value << ...
^
1 error generated.

g++ 是“gcc 版本 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)”,
clang++ 是“Ubuntu clang 版本 3.4-1ubuntu1(主干)(基于 LLVM 3.4)”

两者都在 x86_64 linux 中。

命令行是:
clang++ -std=c++11 -o comaprison comaprison.cpp
g++ -std=c++11 -o comaprison comaprison.cpp

那么,我是否使用此代码在 c++11 标准之外做任何事情,还是两个编译器都有问题?。

请注意,如果我删除了 g++ 有问题的行但留下了 clang++ 有问题的行,则代码将编译并与 g++ 一起使用,如果我删除了 clang++ 有问题的行并留下了 g++ 有问题的行,则代码可以编译并与 clang++ 一起工作

另请注意,我使用了两个模板化结构来强制编译器在编译时解析函数。

感谢您的时间和经验。

最佳答案

更新:

  • GCC 阻塞您的函数 stringlength .尝试这个:
    constexpr size_t stringlength(char const* str, size_t i=0)
    {
    return str ? (str[i] ? 1 + stringlength(str, i+1) : 0) : 0;
    }
  • 对于 GCC 4.6.3 这似乎是可疑的:
    static constexpr int const* c = &a[0];
    static constexpr int const* d = &b[0];

    尝试这个:
    static constexpr int* c = &a[0];
    static constexpr int* d = &b[0];

  • 旧答案:

    您的代码似乎是正确的,并且使用 GCC 4.6.3 也可以编译。
    int main()
    {
    const char* a = "hallo";
    const char* b = "qallo";
    std::cout << is_equal(a,b,5) << std::endl;
    constexpr const char* c = "hallo";
    std::cout << is_equal(a,c,5) << std::endl;
    }

    请注意,您提供给函数的字符串是常量。

    here constexpr 允许什么.

    关于c++11 - 使用 c++11 标准中的 constexpr 错误还是我发现了一些编译器错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22790730/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com