小编ior*_*ate的帖子

可变参数模板的部分特化

考虑以下类模板"X"及其部分特化.

template <class ...Types>
struct X {};               // #1

template <class T1>
struct X<T1> {};           // #2

template <class T1, class ...Types>
struct X<T1, Types...> {}; // #3

X<int> x;                  // #2 or #3 ?
Run Code Online (Sandbox Code Playgroud)

我怀疑X <int>是不明确的.这是因为:

很明显,#2和#3都比#1更专业,现在比较#2和#3.根据14.5.5.2,让我们考虑以下哪个#2'和#3'更专业.

template <class T1>
void f(X<T1>);             // #2'

template <class T1, class ...Types>
void f(X<T1, Types...>);   // #3'
Run Code Online (Sandbox Code Playgroud)

根据14.8.2.4,第一步是模板参数推导,使用#2'作为参数模板,#3'作为参数模板.给定唯一的参数类型是X <A1>,推导出的T1是A1,而Types是空的.

A = X<A1>, P = X<T1, Types...>  =>  T1 = A1, Types = {}
Run Code Online (Sandbox Code Playgroud)

第二步是使用#3'作为参数模板,使用#2'作为参数模板.鉴于唯一的参数类型是X <A1,Args ...>,根据14.8.2.5/9(注意该段最近由N3281修订),Args被简单地忽略,推断的T1是A1并且参数推断成功.

A = X<A1, Args...>, P = …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-specialization variadic-templates c++11

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

std :: piecewise_construct不会导致ODR违规吗?

std::piecewise_construct在<utility>中定义,因为它已声明,因此具有内部链接constexpr.我想知道std::piecewise_construct在标题中使用是否会违反ODR.例如:

a.hpp

#include <utility>
#include <tuple>

struct point
{
    point(int x, int y)
      : x(x), y(y)
    {}

    int x, y;
};

inline std::pair<point, point> f(int x1, int y1, int x2, int y2)
{
    return {
        std::piecewise_construct,
        std::forward_as_tuple(x1, y1), std::forward_as_tuple(x2, y2)
    };
}
Run Code Online (Sandbox Code Playgroud)

翻译单位1

#include "a.hpp"
Run Code Online (Sandbox Code Playgroud)

翻译单位2

#include "a.hpp"
Run Code Online (Sandbox Code Playgroud)

TU 1中的std::piecewise_constructin表示f与TU 2中的对象不同f.我怀疑f违反了ODR.

N3290(也可能是ISO/IEC 14882:2011)表示以下情况是ODR的例外,在3.2/5中:

如果对象在D的所有定义中具有相同的文字类型,并且该对象使用常量表达式(5.19)初始化,并且值(但不是地址),则名称可以引用具有内部链接或无链接的const对象使用该对象,并且该对象在D的所有定义中具有相同的值;

f满足几乎所有要求,但"使用对象的值(但不是地址)"对我来说似乎很模糊.确实std::piecewise_construct_t没有状态,但是对分段构造函数的std::pair调用涉及调用隐式声明的复制构造函数std::piecewise_construct_t,其参数是const std::piecewise_construct_t &.地址是"用过的",不是吗?

我很困惑. …

c++ one-definition-rule linkage constexpr c++11

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