经过一段时间的弄清楚我的问题后,我发现编译器如何从一组“标签”(非类型模板参数)中推导出模板参数真的很有趣。但看起来编译器只理解“逐字节”相等规则。
我的意思是这段代码:
struct S1 {
constexpr S1(int v) : _v(v)
{};
constexpr bool operator == (const S1& other) { return true;}
int _v;
};
template <S1 Tag, typename ValueType>
struct TagedValue { ValueType value; };
struct Test : TagedValue<S1{0}, int>, TagedValue<S1{1}, double> {};
template <S1 Idx, typename T>
auto& get(TagedValue<Idx, T>& test) {
return test.value;
}
int main()
{
Test test;
get<S1{1}>(test); // Still compiles, even though S1{0} == S1{1}
static_assert(S1{0} == S1{1});
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我已经定义了我自己的,operator ==它基本上是说:“任何两个实例都是相等的”。但看起来为了在函数 …
使用 C++ 20 概念,我们可以这样写:
#define has_method(CLASS_NAME, METHOD_NAME) \ // Can be generalized of course, but it's just to illustrate the idea
[]<typename TEMPLATE_ARG>() \
{ \
return requires{ std::declval<TEMPLATE_ARG>().METHOD_NAME(); }; \
}.template operator()<CLASS_NAME>()
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
int main()
{
struct S{
void call_1();
void call_2();
void call_3();
void call_4();
};
static_assert(has_method(S, call_1)); // OK
static_assert(has_method(S, call_2)); // OK
static_assert(has_method(S, call_3)); // OK
static_assert(has_method(S, call_4)); // OK
static_assert(has_method(S, call_5)); // Error
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以在has_method没有概念的情况下实现宏(即仅使用 C++17)?
更清楚地说:我需要一个可以接受类和方法名称的宏,我想在 constexpr 上下文中使用这样的宏,就像 constexpr 函数一样。标准 SFINAE 实现需要创建至少两个模板结构,这使得很难(或不可能)将所有这些都放入一个宏中。所以我的问题是否实际上是不可能的。
它是一个编译器错误(我使用VS2013的Visual C++ 12)或者我不明白的东西?但我收到警告C4101:'a':此代码中未引用的局部变量
class A
{
public:
static int i;
};
int A::i;
int main()
{
A a;
a.i = 9;
}
Run Code Online (Sandbox Code Playgroud) 我试图弄清楚如何为 sqr 运算编写“完全通用函数”(它实际上可以是乘法、除法、加法,并不重要)。
考虑下面的代码
#include <iostream>
struct A
{
int val = 2;
A() = default;
A(const A&) = delete; // To make sure we do not copy anything
A(A&& a) = delete; // To make sure we do not move anything
auto operator=(auto) = delete; // To make sure we do not assign anything
// This is important part, we do not want to create a new object on each multiplication.
// We want just to update the old …Run Code Online (Sandbox Code Playgroud)