以下代码被GCC 7.2和clang 5.0.0接受,但被Microsoft VS 2017 15.5.0 Preview 5和Intel C++编译器19拒绝:
struct S { };
constexpr int f(S)
{
return 0;
}
int main()
{
auto lambda = [](auto x)
{
constexpr int e = f(x);
};
lambda(S{});
}
Run Code Online (Sandbox Code Playgroud)
微软:
<source>(12): error C2131: expression did not evaluate to a constant
Run Code Online (Sandbox Code Playgroud)
英特尔:
<source>(12): error: expression must have a constant value
constexpr int e = f(x);
^
<source>(12): note: the value of parameter "x" (declared at line 10) cannot be used as a constant …Run Code Online (Sandbox Code Playgroud) 是否可以将条件作为参数传递给操作?
这是一个例子.
public void Test(Action action, Condition condition);
Run Code Online (Sandbox Code Playgroud)
...
Test( () => Environment.Exit(0), () => variable == variable2 );
Run Code Online (Sandbox Code Playgroud) 我在std :: unordered_set中存储指针,因为我不想要任何重复(我删除了集合中的指针,所以如果有重复,我会尝试删除已经删除的指针).我在这些集合中循环很多,因为我知道std :: vector是最快的循环容器(连续内存),我想知道std :: unordered_set是否也是这样做的.
如果没有,会使用std :: vector并检查指针是否被删除更快?
考虑以下代码(实例):
#define TEST_VA(mX, ...) TEST
#define STRINGIFY_IMPL(mX) #mX
#define STRINGIFY(mX) STRINGIFY_IMPL(mX)
#include <iostream>
int main()
{
std::cout << STRINGIFY(TEST_VA(1)) << std::endl;
std::cout << STRINGIFY(TEST_VA()) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
clang++ 3.4抱怨:
main.cpp:9:37: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
std::cout << STRINGIFY(TEST_VA(1)) << std::endl;
^
main.cpp:1:9: note: macro 'TEST_VA' defined here
#define TEST_VA(mX, ...) TEST
^
main.cpp:10:33: warning: must specify at least one argument for '...' parameter of variadic macro …Run Code Online (Sandbox Code Playgroud) 有没有办法创建一个COUNTER()宏(遵循C++ 11/14标准),它被扩展为每次COUNTER()调用时增加1的数字?
我已经考虑过了,但却找不到让它发挥作用的方法.我没有找到在COUNTER()宏中存储"状态"的方法.
例:
#define COUNTER() <...> // Implementation goes here...
#define UNIQUE_NAME_1() TEST ## COUNTER()
#define UNIQUE_NAME_2() TEST ## COUNTER()
// Note how the COUNTER() macro can be used with other macros
// (it cannot be implemented with C++ code)
int main() {
std::cout << STRINGIFY(UNIQUE_NAME_1()) << std::endl;
std::cout << STRINGIFY(UNIQUE_NAME_2()) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
预期产量:
TEST0
TEST1
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个函数,该函数以一个形式返回一个可变参数包的子集std::tuple.理想情况下,该函数不应具有运行时开销(没有不必要的副本),并且应该允许用户访问lvalue引用并修改它们.
应保持值类型,lvalue引用和const lvalue引用.Temporaries(rvalue引用)应该"转换"为值类型,以避免创建无效引用(对临时引用的引用).
期望结果的示例:
int lr = 5;
const int& clr = lr;
auto t = make_subpack_tuple(lr, clr, 5);
static_assert(is_same
<
decltype(t),
std::tuple<int&, const int&, int>
>{}, "");
// Ok, modifies lr:
std::get<0>(t) = 10;
// Compile-time error, intended:
// std::get<1>(t) = 20;
// Ok, 5 was moved into the tuple:
std::get<2>(t) = 30;
Run Code Online (Sandbox Code Playgroud)
示例不完整实施:
template<typename... Ts>
auto make_subpack_tuple(Ts&&... xs)
{
return std::tuple
<
some_type_trait<decltype(xs)>...
>
(
std::forward<decltype(xs)>(xs)...
);
} …Run Code Online (Sandbox Code Playgroud) 我创建了一个简单的类型特征来删除右值引用:
template <typename T>
struct remove_rvalue_reference { using type = T; };
template <typename T>
struct remove_rvalue_reference<T&&> { using type = T; };
template <typename T>
using remove_rvalue_reference_t =
typename remove_rvalue_reference<T>::type;
Run Code Online (Sandbox Code Playgroud)
我用它来实现一个copy_if_rvalue(x)函数,其返回类型取决于传递的参数:
template <typename T>
constexpr auto copy_if_rvalue(T && x)
-> remove_rvalue_reference_t<decltype(std::forward<decltype(x)>(x))>
{
return std::forward<decltype(x)>(x);
}
Run Code Online (Sandbox Code Playgroud)
为了确保函数返回正确的类型,我编写了一些简单的静态断言:
// literal
static_assert(std::is_same<
decltype(copy_if_rvalue(0)), int
>{});
// lvalue
int lv = 10;
static_assert(std::is_same<
decltype(copy_if_rvalue(lv)), int&
>{});
// const lvalue
const int clv = 10;
static_assert(std::is_same<
decltype(copy_if_rvalue(clv)), const int& …Run Code Online (Sandbox Code Playgroud) 我在我的一个真实项目中遇到了一个难以调试的情况,我不小心访问了已被移动的lambda中的局部变量的引用.访问是从另一个线程完成的,但移动的lambda保持活着直到第二个线程完成.
该错误仅在禁用优化时发生,并且是由粗心重构引起的.
我创建了一个最小的例子(可在wandbox上找到),它可以重现这个问题:
struct state
{
int x = 100;
};
template <typename TF>
void eat1(TF&& f)
{
// Call the lambda.
f();
// Simulate waiting for the second thread
// to finish.
std::this_thread::sleep_for(1000ms);
}
template <typename TF>
void eat0(TF&& f)
{
// Move the lambda to some other handler.
eat1(std::forward<TF>(f));
}
void use_state(state& s)
{
// Will print `100`.
std::cout << s.x << "\n";
// Separate thread. Note that `s` is captured by
// reference. …Run Code Online (Sandbox Code Playgroud) 我试图constexpr通过方法更改对象成员的值但我不明白为什么它不适用于这种特定情况:
#include <iostream>
struct test
{
int m_counter = 0;
constexpr test()
{
m_counter++;
m_counter++;
increment();
increment();
increment();
}
constexpr void increment()
{
m_counter++;
}
constexpr int value() const
{
return m_counter;
}
};
template<int value>
constexpr void check()
{
std::cout << value << std::endl;
}
// constexpr test t; // value = 3, why ?
int main()
{
constexpr test t; // value = 5, ok
check<t.value()>();
}
Run Code Online (Sandbox Code Playgroud)
当我在全局范围内创建对象时,我不明白为什么值为3.msvc和clang在两种情况下都显示5但不是gcc.谁错了?
考虑以下可变参数类模板:
template <typename... Ts>
struct foo
{
template <typename... Us>
foo(Us...) { }
};
Run Code Online (Sandbox Code Playgroud)
如果我尝试以foo下列方式实例化,g ++(trunk)和clang ++(trunk)都很高兴:
auto o = foo{};
Run Code Online (Sandbox Code Playgroud)
auto o = foo();
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)error: cannot deduce template arguments for 'foo' from () auto o = foo(); ^
{}()
这也适用于适当的演绎指南:https: //godbolt.org/g/qReXpM.
c++ language-lawyer variadic-templates template-argument-deduction c++17