由于歧义,GCC 是否允许拒绝以下代码?对我来说,它看起来像一个错误。它与 msvc、clang 和 icc 编译得很好。
见这里:https : //godbolt.org/z/9fsnhx
#include <iostream>
class A
{
public:
template<typename T>
void Foo(int={}){
std::cout << "A";
}
template<
typename... T
,typename... Args
>
void Foo(int={}, Args&&... args)
{
std::cout << "B";
}
};
int main()
{
A a;
a.Foo<int>();
}
Run Code Online (Sandbox Code Playgroud) 我的主要平台是 Windows,这就是我在内部使用 UTF-16(主要是 BMP 字符串)的原因。我想对这些字符串使用控制台输出。
不幸的是没有std::u16cout或std::u8cout,所以我需要使用std::wcout。因此,我必须将 u16strings 转换为 wstrings - 最好(也是最简单)的方法是什么?
在 Windows 上,我知道 wstring 指向 UTF16 数据,因此我可以创建一个简单的 std::u16string_view 使用相同的数据(无转换)。但是在 Linux 上 wstring 通常是 UTF32 ......有没有办法在没有宏和假设 sizeof(wchar_t) == 2 => utf16 的情况下做到这一点?
据我阅读static_cast,以下代码应该工作:
#include <iostream>
#include <string>
class ConvSample
{
public:
template<typename T>
constexpr operator T(){
return {};
}
};
int main()
{
ConvSample aInst;
int i = aInst;
std::cout << i << "\n";
std::string str = static_cast<std::string>(aInst);
std::cout << str << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它与Clang等某些编译器完美配合。但是,例如,没有MSVC或ICC。
请参阅编译器资源管理器
通常,他们抱怨由std :: string提供的未真正起作用的构造函数引起的歧义。
另外,如果我在gcc上启用Wconversion,会遇到分段错误吗?
代码有问题吗?这些错误只是编译器错误吗?如果我将代码更改为不使用模板,则效果很好: Compiler Explorer
在这里,我们有很多关于 const 字段赋值和未定义行为 (UB) 的问题。例如,这个接受的答案说,由于 UB 的原因,不可能为具有 const 字段的类定义复制赋值运算符。
但我检查了 C++ 标准的当前草案版本(N4861)。表示将是 UB [basic.life.8]的部分是:
如果一个对象的生命周期结束后,在该对象占用的存储空间被重用或释放之前,在原对象占用的存储位置上创建一个新的对象,一个指向原对象的指针,一个指向该对象的引用引用原始对象,或者原始对象的名称将自动引用新对象,并且一旦新对象的生命周期开始,可用于操作新对象,如果:...
原始对象的类型不是 const 限定的,并且如果是类类型,则不包含任何类型为 const 限定的非静态数据成员或引用类型,并且
现已替换为:
o1 不是一个完整的 const 对象,并且
我的解释是,下面的代码现在没有 UB。这样对吗?我问这个是因为在样本中,没有简历合格的成员 - 所以我仍然不清楚。
#include <iostream>
struct C {
const int i;
void f() const {
std::cout << i << "\n";
}
C(int i) : i(i) {}
C& operator=( const C& );
};
C& C::operator=( const C& other) {
if ( this != &other ) {
this->~C(); // lifetime …Run Code Online (Sandbox Code Playgroud) 如果我对进行完全限定的调用,则以下代码将使用MSVC,GCC和Clang进行编译std::tuple_cat。但是,如果我对tuple_cat... 进行了无条件的调用,它就不能在任何这些编译器上进行编译,即使我正在这样做using namespace std;!
如果我称该函数为不合格函数,则所有三个编译器都将找到正确的函数-但抱怨的实例化无效std::tuple<void>。
为什么这么重要?这不应该没有区别吗?
#include <tuple>
auto Test() {
using A = std::tuple<void>;
using B = std::tuple<void>;
using namespace std;
using AB = decltype(
#ifdef QUALIFIED
std::
#endif
tuple_cat(std::declval<A>(), std::declval<B>())
);
AB* ptr = nullptr;
return ptr;
}
Run Code Online (Sandbox Code Playgroud)
参见演示。
我想定义一个类,它继承了一堆类,但不隐藏这些类的某些特定方法。
想象一下下面的代码:
template<typename... Bases>
class SomeClass : public Bases...
{
public:
using Bases::DoSomething...;
void DoSomething(){
//this is just another overload
}
};
Run Code Online (Sandbox Code Playgroud)
现在的问题是,如果只有一个类没有具有该名称的成员,DoSomething我会收到错误。我已经尝试过使用宏和 SFINAE 来模拟“如果未定义则忽略”,但要处理所有情况,这会变得非常大且丑陋!你有什么办法解决这个问题吗?
如果我可以定义:“嘿使用 - 忽略缺失的成员”,那就太好了。
这里我有一些示例代码:Godbolt
我想获取参数包的最后一个元素。我用下面的代码GodBolt 做到了:
template<typename... Args>
auto last(Args&&... args){
const auto& last = (args, ...);
return last;
}
Run Code Online (Sandbox Code Playgroud)
但现在我收到警告
逗号运算符的左操作数无效
但这正是我想要实现的......有没有办法说清楚。一般来说,我喜欢收到未使用值的警告,所以我不想禁用所有这些(-Wno-unused-value)。
此外,我可以使用递归模板来实现,但这里的折叠表达式似乎更好。