我有以下代码:
#include <iostream>
class A;
int main()
{
std::cout << std::is_constructible<A>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
当我使用GCC 8.3时,此代码会编译。但是,当我使用Clang 8.0时,出现编译错误,即不能在类型特征中使用不完整的类型。
哪一个是正确的?是否允许我使用is_constructible不完整的类型(预期值为false),还是不允许我使用?
从这个和这个问题来看,我的印象是从原始类型继承会导致编译器错误.但是,以下代码在Ideone上编译并生成预期输出.
#include <iostream>
enum class Test : unsigned short int
{
TEST, TEST2, TEST3, TEST4
};
int main() {
// your code goes here
Test ans = Test::TEST3;
if(ans == Test::TEST3)
{
std::cout << "Here" << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
事实上,这class也是enum改变前两个问答的答案吗?这是标准定义明确的行为吗?
这部分是受这个问题的启发.当我写代码时:
void test(std::string inp)
{
std::cout << inp << std::endl;
}
int main(void)
{
test("test");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
"test"隐式转换const char*为std::string,我得到预期的输出.但是,当我尝试这个:
std::string operator*(int lhs, std::string rhs)
{
std::string result = "";
for(int i = 0; i < lhs; i++)
{
result += rhs;
}
return result;
}
int main(void)
{
std::string test = 5 * "a";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到编译器错误,invalid operands of types 'int' and 'const char [2]' to binary 'operator*'."a" …
请考虑以下代码:
#include <memory>
#include <vector>
class A
{
private:
std::vector<std::unique_ptr<int>> _vals;
};
int main()
{
A a;
//A a2(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器A没有问题地编译它,除非我取消注释A a2(a);它抱怨复制构造函数std::unique_ptr被删除的那一行,因此我不能复制构造A.然而,即使我将该行留下注释,编译器B也会提出投诉.也就是说,当我实际尝试使用它时,编译器A只生成一个隐式定义的复制构造函数,而编译器B则无条件地这样做.哪一个是正确的?请注意,如果我使用std::unique_ptr<int> _vals;而不是std::vector<std::unique_ptr<int>> _vals;两个编译器正确地隐式删除复制构造函数和赋值运算符(std::unique_ptr具有显式删除的复制构造函数,而std::vector不是).
(注:获取代码编译器B到编译是很容易的 - 只要明确地删除拷贝构造函数和赋值运算符,并且它能够正常工作这不是问题的问题,它是要了解正确的行为.)
c++ copy-constructor assignment-operator language-lawyer c++11
我有以下代码:
#include <iostream>
template<size_t N>
class A
{
};
template<int N, typename T> class B;
template<int N>
class B<N, A<N>>
{
};
int main()
{
B<3, A<3>> b;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,B模板化的int时间A是模板化的size_t,这是unsigned long我正在使用的两个编译器.
当我使用编译器1(当前编译器)时,一切都按照我期望的方式编译和工作.当使用编译器2(一个我们正在向),我得到一个编译器错误,指出没有模板专业化B接受一个unsigned long-它解释3为unsigned long因为它需要一个A,但后来找不到任何事情B.修复是显而易见的, - 只需更改B以采取一个size_t(或更改A为采取int) - 但我想知道哪个是标准严格正确.我的直觉是它是编译器2(抛出错误的那个).
我上课了
class A
{
public:
class Key
{
Key() {}
Key(Key const &) {}
};
A(Key key, int a = 5) {}
};
Run Code Online (Sandbox Code Playgroud)
构造函数Key是私有的,因此没有人应该能够构造一个对象A.但是,使用以下代码:
int main() {
A a(A::Key()); // this compiles !!!
A a2(A::Key(), 5); // this doesn't
// somehow defaulting the argument causes the private constructor
// to be OK - no idea why
return 0;
}
Run Code Online (Sandbox Code Playgroud)
通过int a在我的构造函数中使用默认参数,编译器很乐意编译我的用法,A::Key()尽管它是私有的.但是,如果我明确地给出了一个值a,那么编译器会正确识别我正在尝试使用私有构造函数并输出错误.为什么是这样?有没有办法强制编译器在第一个例子中出错?
请看这里的实例.
使用GCC编译器时,该-ftree-vectorize选项会启用自动矢量化,并且在使用时会自动设置此标志-O3。它可以向量化到什么水平?即,我将获得SSE2,SSE4.2,AVX或AVX2指令吗?我知道mavx,mavx2标志等的存在,但是我想知道没有那些特定标志来强制进行特定类型矢量化的编译器在做什么。
我有以下代码:
#include <iostream>
template <class T, typename U = void> class A;
template <class T>
class C
{
public:
typedef T Var_t;
};
template <class T>
class B : public C<T>
{
};
template <class T>
class A<B<T>>
{
public:
A() { std::cout << "Here." << std::endl; }
};
template <class T>
class A<T, typename std::enable_if<
std::is_base_of<C<typename T::Var_t>, T>::value>
::type>
{
public:
A() { std::cout << "There." << std::endl;}
};
int main()
{
A<B<int>> a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当编译器尝试使用参数实例化第二个部分专业化时B<int> …
考虑以下代码:
#include <iostream>
float func(char const & val1, unsigned int const & val2)
{
return val1 + val2;
}
int main() {
double test1 = 0.2;
double test2 = 0.3;
std::cout << func(test1, test2) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尽管我将a传递double给采用const引用小于a的类型的函数double(在我的系统上sizeof(double) == 8,while sizeof(unsigned int) == 4和sizeof(char) == 1按定义),但该函数仍可编译和运行。如果引用不是const,则编译失败(例如, float func(char & val1, unsigned int & val2)而不是当前定义),并显示以下错误:
不能将'char&'类型的非常量左值引用绑定到'char'类型的右值
在Godbolt上使用GCC,Clang,ICC和MSVC进行测试时,我得到的行为完全相同,因此它看起来是标准的。导致该接受的const-references是什么呢,而引用不是?另外,我曾经使用过-Wall -pedantic-为什么我没有收到有关转换范围缩小的警告?当函数按值传递而不是按引用传递时...
阅读StackOverflow问答这样和这个,看起来从STL容器继承通常是一个坏主意.我不打算在生产代码中这样做; 但是,我想知道它是否会给我一个有效的快速和肮脏的测试.
在我们的代码中,我们大量使用STL,我们希望测试如何将内存与64字节边界对齐会影响代码的性能.我打算通过编写一个简单的自定义分配器来测试这个,并且有一个简单的类继承std::vector了类中唯一的变化,即默认分配器是我的自定义分配器而不是std::allocator简单地编写脚本来使用sed和替换所有的实例std::vector和我的新班级.使用这种方法,我将永远不会有任何指针进入基类(所有实例std::vector都已被替换,所以任何指针都将是我的自定义类型),这似乎是从STL继承的最大问题.这是一种有效的方法吗?还有其他更容易/更安全的替代方案吗?这是一个300万行代码库,因此手动更改所有std::vector使用自定义分配器的实例至少可以说是非常非常耗时的任务.
我有以下代码:
#include <iostream>
#include <type_traits>
template <typename T, typename std::enable_if
<std::is_convertible<int, T>::value, T>::type>
void func(T a)
{
std::cout << a << std::endl;
}
template <typename T, typename std::enable_if
<!std::is_convertible<int, T>::value, T>::type>
void func(T a)
{
a.print();
}
class Test
{
public:
void print()
{
std::cout << "Test" << std::endl;
}
};
int main()
{
func(3);
func("Test");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用此代码,我希望第一个调用func打印输出3(int实际上可以转换为int,应该调用第一个专业化名称),第二个调用func打印输出Test(Test()不能转换为int,所以应该调用第二个专业化名称)。但是,我得到了一个编译器错误:
prog.cpp:在函数'int main()'中:
prog.cpp:27:8:错误:没有匹配的函数调用'func(int)'
prog.cpp:5:6:注意:候选:模板[类T,类型名称std …
在下面的代码中,我得到两个构造函数调用Test u = "u";.但是,如果我注释掉析构函数,那么我只得到一个构造函数调用.这是为什么?
#include <iostream>
template<class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os)
{
t.print(os);
return os;
}
class Test
{
public:
template<typename T>
Test(T&& t)
{
std::cout << "Test " << t << '\n';
}
~Test() = default; // if commented out removes one construction
void print(std::ostream& os) const
{
os << "[with T = Test]";
}
};
int main()
{
Test u = "u"; // two constructors (second, a temporary, with T …Run Code Online (Sandbox Code Playgroud)