以下代码使用GCC 8.2编译,但不与Clang 6.0.1编译:
// A struct named Foo.
struct Foo
{
// Data member of type 'int'.
int val;
// Default constructor (constexpr).
constexpr Foo() noexcept : val(0) {}
};
// A struct named Bar.
struct Bar : Foo
{
// Make use of the constructors declared in Foo.
using Foo::Foo;
// A constructor taking an object of type Foo.
// COMMENTING THIS CONSTRUCTOR SOLVE THE COMPILATION ISSUE.
constexpr Bar(Foo const obj) noexcept : Foo(obj) {}
};
// A struct …Run Code Online (Sandbox Code Playgroud) GCC 7.3.1 compile the below code while clang 8.0.0 does not. I would like to know if this syntax is valid (in which case I will report it as a possible clang bug).
Thanks for your help.
template<typename FOO>
struct Foo
{
using Value = int;
template<Value VALUE>
struct Bar;
};
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
struct Foo<FOO>::Bar { static void test(); };
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test() {}
int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)
The error message …
GCC 8.2.1和MSVC 19.20编译以下代码,但是Clang 8.0.0和ICC 19.0.1不能这样做。
// Base class.
struct Base {};
// Data class.
struct Data { int foo; };
// Derived class.
struct Derived : Base, Data { int bar; };
// Main function.
int main()
{
constexpr int Data::* data_p{ &Data::foo };
constexpr int Derived::* derived_p{ data_p };
constexpr int Base::* base_p{ static_cast<int Base::*>(derived_p) };
return (base_p == nullptr);
}
Run Code Online (Sandbox Code Playgroud)
Clang 8.0.0的错误消息如下:
case.cpp:16:33: error: constexpr variable 'base_p' must be initialized by a constant expression
constexpr int Base::* base_p{ …Run Code Online (Sandbox Code Playgroud) 下面的示例程序代码背后的想法是说明如果初始化程序列表构造函数在给定恰好一个元素时不等同于默认复制构造函数,则可能导致Clang出现意外结果.
它还表明Clang和GCC在复制构造函数和初始化列表构造函数之间没有实现相同的优先级,这实际上使得对于可移植代码不可能使用这种类型的初始化列表构造函数.
// Include directive.
#include <initializer_list>
// The struct used in this case.
struct Foo
{
// Member value.
int val;
// Default constructor.
Foo() : val(0) {}
// Initializer list constructor.
Foo(std::initializer_list<Foo>) : val(2) {}
};
// Main function.
int main()
{
// Default constructed Foo object.
Foo foo_zero;
// It is not clear to me which constructor
// should be called by the following statement.
Foo foo_test = { foo_zero };
// Return exit code.
// Clang …Run Code Online (Sandbox Code Playgroud) 当使用模板别名作为声明部分特化的模板类的参数时,我面临着某种意外的结果.在某些情况下,我甚至观察到GCC 8.2和Clang 6.0.0不同意结果.可以在下面找到说明我的案例的代码.
// A template struct named Foo.
template<typename>
struct Foo {};
// A template alias for type Foo.
template<typename TYPE>
using AliasFoo = Foo<TYPE>;
// A variadic template alias for type Foo.
template<typename... ARGS>
using VariadicAliasFoo = Foo<ARGS...>;
// A template struct named Bar.
template<template<typename...> class TEMPLATE, typename TYPE>
struct Bar
{
static constexpr bool value = false;
};
// Partial specialization of template struct Bar.
template<template<typename...> class TEMPLATE, typename... ARGS>
struct Bar< TEMPLATE, TEMPLATE<ARGS...> >
{
static …Run Code Online (Sandbox Code Playgroud)