标签: template-argument-deduction

模板函数类型推导和运算符<<

当我用MSVC++编译以下代码时,我收到一个错误:

struct A
{
    template<typename T>
    void operator<<(T&& x)
    {
    }

};
void f()
{
}
int main()
{
    A().operator<<( f );  // ok
    A() << f;             // error

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

g ++clang都编译好这段代码.AFAIK,' ok '和' error '行完全相同,并且类型T被推导为void(&)().或者是void()和允许对函数的右值引用?如果是这样,他们的意思是什么?这样通过引用传递函数是否可以?它是否无法编译' 错误 '行的MSVC++错误?BTW,错误输出:

no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion)
could be 'void A::operator <<<void(void)>(T (__cdecl &&))'
with[ T=void (void) …
Run Code Online (Sandbox Code Playgroud)

c++ reference visual-c++ c++11 template-argument-deduction

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

类模板参数推导因派生类而失败

#include <utility>

template<class T1, class T2>
struct mypair : std::pair<T1, T2>
{ using std::pair<T1, T2>::pair; };

int main()
{
    (void)std::pair(2, 3); // It works
    (void)mypair(2, 3);    // It doesn't work
}
Run Code Online (Sandbox Code Playgroud)

以上是否形成良好?

如果继承构造函数,是否可能在第二种情况下推导出类模板参数?构建者是否std::pair参与创建隐式演绎指南mypair

我的编译器是g ++ 7.2.0.

c++ templates g++ template-argument-deduction c++17

14
推荐指数
2
解决办法
1007
查看次数

从std :: function调用签名中减去模板参数

考虑这个模板功能:

template<typename ReturnT>
ReturnT foo(const std::function<ReturnT ()>& fun)
{
    return fun();
}
Run Code Online (Sandbox Code Playgroud)

为什么编译器不能ReturnT从传递的调用签名中推断出来?

bool bar() { /* ... */ }

foo<bool>(bar); // works
foo(bar); // error: no matching function call
Run Code Online (Sandbox Code Playgroud)

c++ templates std-function template-argument-deduction

13
推荐指数
2
解决办法
2398
查看次数

涉及非推导参数包的函数指针的参数类型的模板参数推导

这类似于问题,但更具体的情况.这次,没有编译器按预期工作.

template<class T>
struct nondeduced
{
    using type = T;
};

template<class T>
using nondeduced_t = typename nondeduced<T>::type;

template<class... T, class U>
void f(void(*)(nondeduced_t<T>..., U)) {}

void g(int, char) { }

int main()
{
    f<int>(g); // error?
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,T无法推导出参数包,但编译器应该能够U在显式参数替换pack之后推导出T(即int在这种情况下为single ).

预计上述内容也可以在没有nondeduced_t诀窍的情况下工作:

template<class... T, class U>
void f(void(*)(T..., U)) {}
Run Code Online (Sandbox Code Playgroud)

因为T根据[temp.deduct.type] p5,参数包已经在非推导的上下文中

未推断的上下文是:

  • 函数参数包,不会出现在参数声明列表的末尾.

不幸的是,我测试过的编译器(g ++/clang)都没有接受代码.值得注意的是,下面的内容适用于g ++和clang.

template<class... T>
void f(void(*)(nondeduced_t<T>..., char)) {}
Run Code Online (Sandbox Code Playgroud)

而且,这对两者都不起作用:

template<class... …
Run Code Online (Sandbox Code Playgroud)

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

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

为什么在GCC中std :: set的演绎失败?

我有一个std::set允许从迭代器范围中扣除的东西.

#include <iostream>
#include <set>

int main() 
{
   std::set s1 = {1,2,3,4}; 
   std::set s2(s1.begin(), s1.end());
}
Run Code Online (Sandbox Code Playgroud)

上述程序未能在GCC中编译.

为什么演绎失败std::set

c++ gcc set template-argument-deduction c++17

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

为什么复制扣除候选人需要作为单独的扣除指南?

template <typename T> struct A {
    A(T);
    A(const A&);
};

int main()
{
    A x(42); // #1
    A y = x; // #2
}
Run Code Online (Sandbox Code Playgroud)

据我了解,T#1将使用第一个ctor生成的隐式演绎指南推导出.然后x将使用该ctor初始化.

但是对于#2,T将使用复制演绎候选人推断(根据我的理解,这是演绎指南的特定情况)(然后y将使用第二个ctor初始化).

为什么不能T使用复制版本生成的(隐含)演绎指南来推导#2?

我想我只是不明白复制演绎候选人的一般目的.

c++ templates template-argument-deduction argument-deduction c++17

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

为什么C++ 17标准没有带来部分类模板参数推导?

我希望能够使用新的模板参数推导的地方之一就是构建带有自定义比较器的std::set's/std::maps /任何其他容器 - 我的目标是创建一个单行语句,这将创建一个高效的用lambda比较器设置.自C++ 11以来我能做的是:

std::set<int, std::function<bool(int, int)>> s([](int a, int b) {return a > b;});
Run Code Online (Sandbox Code Playgroud)

但由于它使用std::function,它明显变慢.

另一种选择是:

auto mycomp = [](int a, int b) {return a > b; };
std::set<int, decltype(mycomp)> s(mycomp);
Run Code Online (Sandbox Code Playgroud)

它完成了工作,但1)它需要2行,并创建mycomp变量2)我需要mycomp显式传递的类型.

正如我在参考页面上看到的那样,没有一个标准容器有针对这种情况的扣除指南.不幸的是,我担心它甚至无法用当前的语言标准(C++ 17)完成,因为人们可以找到:

仅当不存在模板参数列表时,才会执行类模板参数推导.如果指定了模板参数列表,则不会进行演绎.

这背后的原因是什么?为什么他们不允许部分论证扣除?我想它有些问题我忽略了,但在我看来,它会有所帮助.

c++ templates template-argument-deduction argument-deduction c++17

13
推荐指数
3
解决办法
646
查看次数

构造函数中的完美转发(C++ 17)

请考虑以下代码

struct A {
    A(int id) : id_ { id } {}

    A(const A& rhs) { std::cout << "cctor from " +
        std::to_string(rhs.id_) << std::endl; }
    A(A&& rhs) { std::cout << "mctor from " +
        std::to_string(rhs.id_) << std::endl; }

    int id_;
};

template<typename T>
struct B1 {
    constexpr B1(T&& x) noexcept : x_ { std::forward<T>(x) } {}

    T x_;
};

template<typename T>
struct B2 {
    constexpr B2(T&& x) noexcept;

    T x_;
};

template<typename T>
constexpr
B2<T>::B2(
    T&& x
) noexcept …
Run Code Online (Sandbox Code Playgroud)

c++ gcc language-lawyer template-argument-deduction c++17

13
推荐指数
2
解决办法
1279
查看次数

非类型模板参数推导中的类型冲突

#include<type_traits>

template <typename T, T>
struct A { };

template <typename T, T t>
void f(A<T, t>) {
}

int main() {
    f(A<const int, 0>{});
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/n6bcj5rjM


该程序在 C++14 和 C++17 模式下被 GCC 和 ICC 接受,在 C++14 模式下被 Clang 接受,但在 C++17 模式下被 Clang 拒绝,在任一模式下被 MSVC 拒绝。


拒绝是通过这样的诊断:

<source>:12:5: error: no matching function for call to 'f'
    f(A<const int, 0>{});
    ^
<source>:7:6: note: candidate template ignored: deduced conflicting types for parameter 'T' ('const int' vs. 'int')
void f(A<T, t>) {
     ^ …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer template-argument-deduction non-type-template-parameter

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

当模板参数全部被推导时,它们的顺序是否重要?

我发现 Clang、GCC 和 MSVC 之间存在差异,其中 GCC 和 Clang 执行了我所期望的操作:

#include <Eigen/Core>

template <typename Indices, typename T, int Rows> //< Bad
//template <typename Indices, int Rows, typename T> //< OK
//template <typename T, int Rows, typename Indices> //< OK
//template <typename T, typename Indices, int Rows> //< Bad
//template <int Rows, typename Indices, typename T> //< Bad
//template <int Rows, typename T, typename Indices> //< Bad
void f(
    const Eigen::Matrix<T, Rows, 1>&,
    const Indices&
) {}


int main() {
    f(Eigen::Matrix<double, 6, …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer template-argument-deduction

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