我想在我的C++程序中使用类似typedef的东西来增强类型安全性.
举个例子,假设我有两个功能
void function1(unsigned idOfType1);
void function2(unsigned idOfType2);
Run Code Online (Sandbox Code Playgroud)
那么我可以错误地将idOfType2传递给function1,反之亦然.我希望编译器在这种情况下给我一个错误.我知道我可以将这些unsigned包装在一个结构中,但是我必须提供一个字段名称并使用它.来访问它们,这有点不方便.这有什么好办法吗?
编辑:据我所知typedef,这不会用于此目的,因为它只是一种类型的简写,不会用于类型检查.
考虑以下程序:
#include <tuple>
#include <vector>
#include <iostream>
#include <type_traits>
template <class T>
struct ordered {};
template <class... T>
struct ordered<std::tuple<T...>>
{
using type = /* a reordered tuple */;
};
template <class T>
using ordered_t = typename ordered<T>::type;
int main(int argc, char* argv[])
{
using type1 = std::tuple<char, std::vector<int>, double>;
using type2 = std::tuple<std::vector<int>, double, char>;
std::cout << std::is_same_v<type1, type2> << "\n"; // 0
std::cout << std::is_same_v<ordered_t<type1>, ordered_t<type2>> << "\n"; // 1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该ordered助手有重新排序的元组类型,使得两个元与萨姆斯的类型,但有序的不同导致相同的元组类型:它可以是第一个,第二个,甚至是另一个问题:它只是有相同的大小,相同的元素,但以一个独特的顺序(无论这个顺序如何).
是否可以使用模板元编程技术在编译时执行此操作?
正如cppreference.com所说,
地图通常以红黑树的形式实现。
因此,移动a std::map只是将指针移动到根node+其他信息(例如大小)。为什么std::map移动构造函数未标记为noexcept?
我有以下代码,我无法工作:
struct foo {};
foo foo1 = {};
template <foo& F>
class FooClass {};
template <foo& F>
void foobar(FooClass<F> arg) {
}
int main() {
FooClass<foo1> f;
foobar(f);
}
Run Code Online (Sandbox Code Playgroud)
错误是:
main.cpp:14:5:错误:没有匹配函数来调用'foobar'
注意:候选模板被忽略:替换失败:推导出的非类型模板参数与其对应的模板参数('foo'vs'foo&')的类型不同
是否可以推断左值参考模板参数?如果是这样,应该怎么做?
我有一个关于C++ 0x lambdas的问题.在我的代码中,知道给定类型是否是C++ 0x lambda表达式的类型将是有益的.举个例子:
struct foobar
{
void operator()()
{
}
};
auto lambda = []{};
typedef is_lambda < decltype(lambda) > ::type T; // T would be a true_type
typedef is_lambda < foobar > ::type T; // T would be a false_type
Run Code Online (Sandbox Code Playgroud)
将lambda表达式与函数和成员函数类型区分开来相当容易.函子是另一回事.
我在这里看到的问题是根据即将推出的C++ 0x标准定义lambda表达式; 唯一必须定义的是公共呼叫运营商.然而,对于仿函数也是如此; 测试调用操作符的存在是不足以区分lambda表达式和仿函数.此外,如果不存在仿函数的运算符,则会发生编译器错误,因为SFINAE不适用.这是什么时候发生的?仿函数的调用操作符可能是模板化的.所以,这样的代码:
typedef decltype(&T::operator()) call_type;
Run Code Online (Sandbox Code Playgroud)
将使用非模板化调用运算符的lambda表达式和仿函数,并为模板化调用运算符生成编译器错误.
我相信is_lambda < >只能使用内部编译器功能创建特征.你看到了如何实现这个特性的方法吗?
因此,我试图以某种现代C ++的形式实现点积(https://en.wikipedia.org/wiki/Dot_product),并提出了以下代码:
#include <iostream>
template<class... Args>
auto dot(Args... args)
{
auto a = [args...](Args...)
{
return [=](auto... brgs)
{
static_assert(sizeof...(args) == sizeof...(brgs));
auto v1 = {args...}, i1 = v1.begin();
auto v2 = {brgs...}, i2 = v2.begin();
typename std::common_type<Args...>::type s = 0;
while( i1 != v1.end() && i2!= v2.end())
{
s += *i1++ * *i2++;
}
return s;
};
};
return a(std::forward<Args>(args)...);
}
int main()
{
auto a = dot(1,3,-5)(4,-2,-1);
std::cout << a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在线:https : …
我编写了以下代码g++,并得到了输出,这些代码写在注释中.
template<class T>
void foo(T t) { cout << typeid(t).name() << endl; }
int main() {
foo("f"); //emits "PKc"
foo(string()); //emits "Ss"
}
Run Code Online (Sandbox Code Playgroud)
我知道,这type_info.name()不是标准化的,但有没有办法获得人类可读的结果?
像下面这样的东西会很好
const char *
class string
Run Code Online (Sandbox Code Playgroud) 这是一些示例代码:
#include <iostream>
class Foo
{
public:
explicit Foo(int x) : data(x) {};
Foo& operator++()
{
data += 1;
return *this;
}
void *get_addr()
{
return (void*)this;
}
friend Foo operator + (const Foo& lhs, const Foo& rhs);
friend std::ostream& operator << (std::ostream& os, const Foo& f);
private:
int data;
};
std::ostream& operator << (std::ostream& os, const Foo& f)
{
return (os << f.data);
}
Foo operator + (const Foo& lhs, const Foo& rhs)
{
return Foo(lhs.data + rhs.data);
} …Run Code Online (Sandbox Code Playgroud) 我有以下示例代码:
#include <functional>
#include <iostream>
#include <string>
void f(std::function<const std::string&()> fn) {
std::cout << "in f" << std::endl;
std::cout << "str: " << fn() << std::endl;
}
int main() {
std::string str = "a";
auto fn1 = [&]() { return str; };
auto fn2 = [&]() { const std::string& str2 = str; return str2; };
auto fn3 = [&]() -> const std::string& { return str; };
std::cout << "in main" << std::endl;
std::cout << "fn1: " << fn1() << std::endl; …Run Code Online (Sandbox Code Playgroud) 为什么clang(9.0.0)无法编译此代码?GCC(9.2.0)没问题。
使用typedef int arr[y][z]; arr *a;或auto a = ...可以正常使用,但使用内联类型会产生奇怪的错误消息error: assigning to 'int (*)[y][z]' from incompatible type 'int (*)[y][z]'。这些类型对我来说看起来很兼容。两种不同的类型是否可能具有相同的语法?
#include <iostream>
int main() {
int x, y, z;
std::cin >> x >> y >> z;
int (*a)[y][z];
a = (int(*)[y][z]) new int[x * y * z];
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
for (int k = 0; k < z; k++) …Run Code Online (Sandbox Code Playgroud)