C++11 从c++;11标准还是我发现了一些编译器错误?
我正在使用constexpr关键字并编写以下简单程序:C++11 从c++;11标准还是我发现了一些编译器错误?,c++11,g++,constexpr,clang++,C++11,G++,Constexpr,Clang++,我正在使用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] &
#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;
}
那么,我是在用这段代码做c++11标准之外的事情,还是这两个编译器都有问题
请注意,如果我删除了g++有问题的行,但保留了clang++有问题的行,那么代码将编译并使用g++工作;如果我删除了clang++有问题的行,保留了g++有问题的行,那么代码将编译并使用clang正常工作++
还要注意,我使用两个模板结构强制编译器在编译时解析函数
感谢您的时间和经验。更新:
stringlength
。试试这个:
constexpr size_t stringlength(char const* str, size_t i=0)
{
return str ? (str[i] ? 1 + stringlength(str, i+1) : 0) : 0;
}
static constexpr int const* c = &a[0];
static constexpr int const* d = &b[0];
试试这个:
constexpr size_t stringlength(char const* str, size_t i=0)
{
return str ? (str[i] ? 1 + stringlength(str, i+1) : 0) : 0;
}
static constexpr int* c = &a[0];
static constexpr int* d = &b[0];
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;
}
intmain()
{
const char*a=“你好”;
const char*b=“qallo”;
std::cout您所说的arraylelength
示例不适用于GCC,它适用于GCC 4.7和4.8,除了关于constepr const
的一个无关错误外,也适用于GCC 4.6
至于您的stringlength
示例:这是GCC的一个限制。我知道我已经看到了关于它的错误报告。您可以通过重写stringlength
函数来解决它:
constexpr size_t stringlength(char const* str, size_t len=0)
{
return str ? (str[len] ? stringlength(str, len + 1) : len) : 0;
}
但据我所知,你已经得到的是完全有效的。你能试着把你的例子缩小一点吗?这不像是重模板的C++11
代码从一开始就是一种阅读的乐趣。T\uu
不是你的程序可以使用的名称。鉴于此,编译器所做的一切都是有效的。(但不管是GCC还是clangcare)@mic_e这是“高度模板化的C++11
”?我想知道你在工作时会怎么称呼我的代码。comiler?我想要它。在任何地方带有双下划线的标识符都是保留的。原始形式的stringlength
函数是完全正确的。你的解决方法也是正确的,避免了GCC的错误。我和g++4.8.2-Wall-Wextra-pedantic
不明白为什么2.应该是可疑的.4.6.3不喜欢它…我想说constexpr
意味着const
静态
在这里也不应该是必需的。hvd和您都向我指出gnu编译器的正确工作区。我让troube选择谁应该标记正确的答案,但在阅读评论时,似乎Danvil的答案排在第一位。Y你对arraylength函数在我的原始代码中正确工作的看法是正确的。编辑我的答案。
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;
}
constexpr size_t stringlength(char const* str, size_t len=0)
{
return str ? (str[len] ? stringlength(str, len + 1) : len) : 0;
}