VS2017 15.1无法编译以下代码:
template<int data_size>
struct Data { };
template<int s>
struct Base
{
static constexpr int size() { return s; }
};
template<int s>
struct Derived : Base<s> // struct Derived
{
Data<Base<s>::size()> data;
};
int main()
{
Derived<1> c;
}
Run Code Online (Sandbox Code Playgroud)
错误是:
Run Code Online (Sandbox Code Playgroud)error C2975: 'data_size': invalid template argument for 'Data', expected compile-time constant expression note: see declaration of 'data_size' note: see reference to class template instantiation 'Derived<s>' being compiled
如果我不是从中衍生Derived出来的Base,那么错误就会消失.使用gcc 5.4.0和clang 4.0.0在这两种情况下一切都很好.
这段代码有什么问题吗?
我想实现一个带有仿tuple_map函数的泛型函数,并将仿函数std::tuple应用于此元组的每个元素并返回std::tuple结果.实现非常简单,但问题出现了:这个函数应返回什么类型?我的实现使用了std::make_tuple.然而,在这里 std::forward_as_tuple建议.
更具体地说,实现(为简洁起见,省略了对空元组的处理):
#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>
template<class Fn, class Tuple, std::size_t... indices>
constexpr auto tuple_map_v(Fn fn, Tuple&& tuple, std::index_sequence<indices...>)
{
return std::make_tuple(fn(std::get<indices>(std::forward<Tuple>(tuple)))...);
// ^^^
}
template<class Fn, class Tuple, std::size_t... indices>
constexpr auto tuple_map_r(Fn fn, Tuple&& tuple, std::index_sequence<indices...>)
{
return std::forward_as_tuple(fn(std::get<indices>(std::forward<Tuple>(tuple)))...);
// ^^^
}
template<class Tuple, class Fn>
constexpr auto tuple_map_v(Fn fn, Tuple&& tuple)
{
return tuple_map_v(fn, std::forward<Tuple>(tuple),
std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
}
template<class Tuple, class Fn>
constexpr …Run Code Online (Sandbox Code Playgroud) 人们听到他们的声音感到困惑
int&& x
Run Code Online (Sandbox Code Playgroud)
x具有右值引用类型,但x为左值。误解源于标识符和表达式是不同的事物,类型和值类别也是如此。此外,表达式的类型“在进行任何进一步分析之前已调整”,并且单词“ rvalue”和“ lvalue”可以同时出现在类型名称和值类别名称中。
我想澄清正式定义。假设我们有一个函数:
1 | void f(int&& x) {
2 | ... = x;
3 | ... = std::move(x);
4 | }
Run Code Online (Sandbox Code Playgroud)
以下陈述正确吗?
x是一个标识符(id表达式),它为函数参数命名。其类型为int&&,这是decltype(x)返回的类型。x不是表达式,没有值类别。x是一个表达式。在类型调整之前,其类型为int&&,而在类型变为之后int。值类别为左值。std::move(x)是一个表达式。调整前的类型是int&&-之后int。值类别为xvalue。x具有右值引用类型时,在类型调整之前,我们将其x称为标识符,或者将其x称为表达式。T&或const T&,等等),则该表达式是左值。” 他是指调整前的类型,第二个单词“左值”是指值类别。安东尼·威廉姆斯在他最近的博客文章中谈到了隐藏的朋友。如果我理解正确的话,主要思想是在某些情况下 ADL 无法找到声明为友元的函数。简单的例子:
namespace N {
struct A {
friend void foo(A) { }
};
struct B {
operator A();
};
// (*)
void bar(A) { }
}
void func() {
N::A a;
bar(a); // OK, bar is found via ADL
foo(a); // OK, foo is found via ADL
N::B b;
bar(b); // OK, bar is found via ADL
foo(b); // NOT OK, foo cannot be found
}
Run Code Online (Sandbox Code Playgroud)
在博客文章的所有示例中,友元函数都是在类内定义的。是否可以声明一个友元函数,然后在该点定义它(*),以便它保持隐藏状态?看起来隐藏的朋友只能在类范围(或另一个编译单元)中定义。
我有以下代码:
struct Foo
{
struct Bar
{
std::uint32_t x = -1;
constexpr Bar(std::uint32_t x) : x(x) {}
};
static constexpr Bar CONST_BAR = Bar(0);
};
Run Code Online (Sandbox Code Playgroud)
当我尝试编译它时,出现以下错误:
错误:'constexpr Foo::Bar::Bar(uint32_t)' 在定义完成之前在常量表达式中调用
有人可以向我解释发生了什么吗?据我所知,Bar 的构造函数是在第一次调用之前定义的。
知道为什么以下代码段无法编译吗?它报错“错误:?的操作数:具有不同的类型”
auto lambda1 = [&](T& arg) {
...
};
auto lambda2 = [&](T& arg) {
...
};
auto lambda = condition ? lambda1 : lambda2;
Run Code Online (Sandbox Code Playgroud) 当调用std::sort()a 时std::array:
#include <vector>
#include <array>
#include <algorithm>
int main() {
std::vector<int> foo{4, 1, 2, 3};
sort(begin(foo), end(foo));
std::array<int, 4> foo2{4, 1, 2, 3};
sort(begin(foo2), end(foo2));
}
Run Code Online (Sandbox Code Playgroud)
gcc 和 clang 都在排序上返回错误std::array-- clang 说
错误:使用未声明的标识符“排序”;你的意思是'标准::排序'?
更改以std::sort(begin(foo2), end(foo2))解决问题。
MSVC 按照编写的方式编译上面的代码。
为什么std::vector和之间的待遇不同std::array;哪个编译器是正确的?
取自 GCC 实现type_traits为什么static_cast需要这里?
template <typename _Tp, typename... _Args>
struct __is_nt_constructible_impl
: public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> {};
template <typename _Tp, typename _Arg>
struct __is_nt_constructible_impl<_Tp, _Arg>
: public integral_constant<bool,
// Why is `static_cast` needed here?
noexcept(static_cast<_Tp>(declval<_Arg>()))> {};
Run Code Online (Sandbox Code Playgroud) 我有以下函数来计算平均值:
template<typename... Ts>
auto mean_of(const Ts... values)
{
return (... + values) / static_cast<double>(sizeof...(Ts));
}
Run Code Online (Sandbox Code Playgroud)
使用VS 2017 15.6.0预览3以下代码
std::cout << mean_of(1, 3);
Run Code Online (Sandbox Code Playgroud)
输出2.5.似乎MSVC将折叠表达式解释为1 + 3 / N而不是(1 + 3) / N.如果我在fold表达式周围添加额外的括号,结果是正确的.使用GCC不需要额外的括号.
这是MSVC中的错误还是我们需要额外的括号?
c++ language-lawyer variadic-templates fold-expression c++17
铛(7,8,主干)拒绝以下代码
enum class E {};
inline static constexpr auto e = E{};
// inline static constexpr auto e = nullptr;
template<auto, int> class S;
template<int a, int b> class S<a, b> {};
template<int b> class S<e, b> {};
int main() {
S<0, 0> s;
}
Run Code Online (Sandbox Code Playgroud)
带有错误:
Run Code Online (Sandbox Code Playgroud)error: ambiguous partial specializations of 'S<0, 0>' note: partial specialization matches [with a = 0, b = 0] template<int a, int b> class S<a, b> {}; ^ note: partial specialization matches [with b = …