小编Nik*_*zev的帖子

使用sfinae的别名模板:语言允许吗?

我刚刚发现了以下技术.它看起来非常接近提议的概念语法之一,完全适用于Clang,GCC和MSVC.

template <typename T, typename = typename std::enable_if<std::is_rvalue_reference<T&&>::value>::type>
using require_rvalue = T&&;

template <typename T>
void foo(require_rvalue<T> val);
Run Code Online (Sandbox Code Playgroud)

我试图通过搜索请求找到它,比如"类型别名中的sfinae"并没有得到任何结果.这种技术有没有名称,语言实际上允许它吗?


完整的例子:

#include <type_traits>

template <typename T, typename = typename std::enable_if<std::is_rvalue_reference<T&&>::value>::type>
using require_rvalue = T&&;

template <typename T>
void foo(require_rvalue<T>)
{
}

int main()
{
    int i = 0;
    const int ic = 0;
    foo(i);            // fail to compile, as desired
    foo(ic);           // fail to compile, as desired
    foo(std::move(i)); // ok
    foo(123);          // ok
}
Run Code Online (Sandbox Code Playgroud)

c++ sfinae language-lawyer c++11

26
推荐指数
2
解决办法
467
查看次数

如果在可推导类型上存在替换,则可变参数模板类型推导会使编译器崩溃

我想我在所有编译器中遇到了模板类型演绎错误,但在报告之前我想确定我没有错过任何东西.

考虑一个例子:

#include <utility>

template <std::size_t... I, typename... T>
void foo(std::index_sequence<I...>, decltype(I)..., T...) {}

int main()
{
    foo(std::make_index_sequence<3>{}, 1, 2, 3, 4, 5);
}
Run Code Online (Sandbox Code Playgroud)

decltype(I) 这里用来缩短MWE.

  • GCC: error: too few arguments to function
  • Clang崩溃了 error: no matching function for call to 'foo'
  • MSVC崩溃了 error C3543: 'unknown-type': does not contain a parameter pack

我不明白为什么它没有扣除T,特别是因为它可以用varargs替换参数包(除了MSVC,它再次有ICE).

template <std::size_t... I>
void foo(std::index_sequence<I...>, decltype(I)..., ...) {}
Run Code Online (Sandbox Code Playgroud)

还有很多其他方法可以制作我想要的东西,但这是最短的方式,我没有看到它应该失败的任何理由.

更新:在deducible上替换的已知有效示例是:

template <typename T>
struct type_identity
{ using type = T; };

template <typename T, …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer variadic-templates template-argument-deduction c++14

8
推荐指数
1
解决办法
287
查看次数

变量模板的部分专业化

我知道我可以部分专门化类模板,我知道我不能部分指定函数模板.

变量模板怎么样?我找不到关于它们是否可以部分专业化的文档.

c++ templates partial-specialization language-lawyer variable-templates

6
推荐指数
1
解决办法
416
查看次数

带有enum模板专门化问题的enable_if

我在将GCC编译enable_if应用于模板化类方法的返回值时遇到问题。使用Clang时,我可以enable_ifenumtemplate参数上使用表达式,而GCC拒绝编译此代码。

这是问题描述,初始代码及其后续修改,它们试图使我和编译器满意(不幸的是,不是同时)。

我有一个非模板类Logic,其中包含一个模板类方法computeThings(),其具有enum Strategy 作为一个它的模板的参数。中的逻辑computeThings()取决于编译时Strategy,因此if constexpr是实现的一种合理方法。

变体1

    #include <iostream>
class Logic {
public:
    enum Strategy { strat_A, strat_B };
    // class A and class B are dummy in this example, provided to show that there are several template
    // parameters, and strategy selection effectively results in 
    // partial (not full) templated method specification
    template <class A, class B, Strategy strategy>
    int …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates enable-if c++17

4
推荐指数
1
解决办法
264
查看次数

为什么noreturn / __ builtin_unreachable阻止尾部调用优化

我发现,如果一个被调用的函数没有返回(即标记为_Noreturn/ [[noreturn]]__builtin_unreachable()在调用后有一个),那么所有主要的编译器都不会进行尾部调用优化。这是预期的行为,而不是错过的优化吗?如果是,为什么?

范例1:

#ifndef __cplusplus
#define NORETURN _Noreturn
#else
#define NORETURN [[noreturn]]
#endif

void canret(void);
NORETURN void noret(void);

void foo(void) { canret(); }
void bar(void) { noret(); }
Run Code Online (Sandbox Code Playgroud)

C:https//godbolt.org/z/pJfEe- C ++:https//godbolt.org/z/-4c78K

范例2:

#ifdef _MSC_VER
#define UNREACHABLE __assume(0)
#else
#define UNREACHABLE __builtin_unreachable()
#endif

void f(void);

void foo(void) { f(); }
void bar(void) { f(); UNREACHABLE; }
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/PFhWKR

c c++ noreturn

2
推荐指数
1
解决办法
116
查看次数

虚拟类作为带有 Spirit 的 AST 节点

我正在和一个朋友一起研究一种语言的解释器,我们从一个我猜不是那么明智的决定开始:我们首先制作了所有要执行的元素(实际上是一个由不同类组成的树);但是现在查看 boost 示例,我对如何合并两者感到很困惑。我知道从什么开始(语法),我知道要达到什么(实例化的类彼此拥有),我不知道如何达到它。

我们从没有变量的表达式开始,因此我们查看了精神计算器示例;但我不明白什么时候实例化元素。

表达项示例:

namespace exp
{
class op
    {
    private:
    public:
        virtual double exec(function_scope &fs);

    };

class operand : public op
    {
    private:
        double value;

    public:
        operand(double value);
        double exec(function_scope &fs);
    };

class op_bin : public op
    {
    private:
    public:
        op * ll;
        op* rr;
        op_bin(op* ll, op* rr);
        ~op_bin();
    };

namespace bin
    {
    class sum : public op_bin
        {
        public:
            sum(op* ll, op* rr);
            double exec(function_scope &fs);
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

忽略 exec 函数,它在运行时使用。

例如,代码 5 + (2 …

c++ abstract-syntax-tree boost-spirit

1
推荐指数
1
解决办法
124
查看次数