我有以下代码的问题:
template <typename U>
class lamePtr
{
public:
typedef U* ptr;
};
template <typename U>
class smarterPointer
{
public:
void funFun()
{
typedef lamePtr<U> someType;
someType::ptr query;
}
};
Run Code Online (Sandbox Code Playgroud)
如你所见,我在lamePtr中有一个typedef.在smarterPointer类里面我有一个函数funFun().我想做的是制作另一个typedef someType.直到该行,一切正常,直到我们到someType :: ptr查询行.
我想要发生的是"查询"将成为lamePtr <U> :: ptr(一个简单的值,而不是typedef;).但是,我得到编译错误(使用gcc 4.4.3):
temp.cpp: In member function ‘void smarterPointer<U>::funFun()’:
temp.cpp:15: error: expected ‘;’ before ‘query’Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?
在尝试移植一些代码以在linux中编译时,我得到了特殊的编译错误.通过代码库搜索,我终于设法将其归结为以下代码.
5: // include and using statements
6: template<typename RT, typename T1>
7: RT func(tuple<T1> const& t) {
8: return t.get<0>();
9: }
10: // test code
Run Code Online (Sandbox Code Playgroud)
试着用它我得到错误:
test.cpp: In function <functionName>:
test.cpp:8: error: expected primary-expression before ‘)’ token
Run Code Online (Sandbox Code Playgroud)
代码在Visual Studio中工作正常但由于某种原因我无法弄清楚为什么它不适用于g ++.这里的任何人都知道如何解决这个问题?
尝试键入我的内存对齐方式我提出了以下构造(由于我需要更正GNU版本,因此仍然需要进行一些工作):
#if defined(__GNUG__)
template <typename T>
struct sfo_type {
typedef T* restrict __attribute__((aligned(32))) aptr32;
};
#elif defined(__INTEL_COMPILER)
template <typename T>
struct sfo_type {
typedef T* restrict __attribute__((aligned(32))) aptr32;
};
#endif
Run Code Online (Sandbox Code Playgroud)
然后我尝试像这样使用它:
template<typename T>
class tsfo_vector {
private:
sfo_type<T>::aptr32 m_data;
int m_size;
...
Run Code Online (Sandbox Code Playgroud)
但后来我收到以下错误信息:
/Users/bravegag/code/fastcode_project/code/src/sfo_vector.h(43): error: nontype "sfo_type<T>::aptr32 [with T=T]" is not a type name
sfo_type<T>::aptr32 m_data;
^
Run Code Online (Sandbox Code Playgroud)
任何人都可以在这里建议什么是错的吗?
此问题基于C++参考部分:依赖名称 - 依赖名称的模板消歧器.
我已经理解在模板类中调用模板成员函数时,关键字模板是必要的,以使编译器知道以下括号用于指示模板参数.就像本节中使用的示例一样.
template<typename T>
struct S {
template<typename U> void foo(){}
};
template<typename T>
void bar()
{
S<T> s;
s.foo<T>(); // error: < parsed as less than operator
s.template foo<T>(); // OK
}
Run Code Online (Sandbox Code Playgroud)
但是,在后续部分中,它描述了模板名称何时出现在成员访问表达式中(在 - >之后或之后.),如果在表达式的上下文中存在通过普通查找找到的具有相同名称的模板,则不需要消除歧义. ..
然后它附带以下代码.与前面的例子相比,它定义了set函数,其名称也存在于标准库中.同时,使用std :: set设置为在模板函数中显示设置模板.在这种情况下,即使没有提供关键字模板,它仍然可以正常工作.
#include <set>
using std::set; // makes 'set' visible to lookup from bar
template<typename T>
struct S {
template<typename U> void set(){}
};
template<typename T>
void bar()
{
S<T> s;
s.set<T>(); …Run Code Online (Sandbox Code Playgroud) 我通过编译以下示例遇到了以下问题:
template <int N>
class Matrix {
public:
template <int Idx>
int head() {
return Idx;
}
};
template <typename T>
class Test {
static constexpr int RayDim = 3;
public:
int func() const {
Matrix<RayDim> yF;
return yF.head<1>();
// ^ is template keyword required here?
}
};
struct Empty {};
void test() {
Test<Empty> t;
}
Run Code Online (Sandbox Code Playgroud)
链接到编译器资源管理器:https : //godbolt.org/z/js4XaP
该代码使用GCC 9.2和MSVC 19.22进行编译,但不能使用clang 9.0.0进行编译。Clang指出需要template关键字。如果static constexpr int RayDim = 3;移入int func() constclang接受它。
如代码块中的注释所述,是否需要template关键字yF.head<1>()?
template<class T>
T::type<int> f(){
}
Run Code Online (Sandbox Code Playgroud)
根据 [temp.names#3.4]
如果 < 跟随的名称不是转换函数 id 和
- [...]
- 它是 using 声明符 ([namespace.udecl])、声明符 id ([dcl.meaning]) 或嵌套名称说明符([temp.资源])。
根据 [temp.res#general-4.3.1],T::type<int>由于以下规则,确实满足上述规则(强调我的)
一个合格的或不合格的名称被说成是在类型仅上下文如果它的终端名称
- [...]
- a 的 decl-specifier-seq 的 decl-specifier
- [...]
- 命名空间范围内的简单声明或函数定义,
T::type<int>是命名空间范围内模板函数的函数定义的声明说明符f,因此终端名称type被称为仅在类型上下文中。
另外,根据 [temp.res#general-5]
终端名称是相关的并且在仅类型上下文中的限定 ID 被认为是表示类型。
因此,由于 [temp.names#3.4] ,符号<inT::type<int>被解释为模板参数列表的分隔符,而T::type<int>由于 [temp.res#general-5],qualified-id被认为表示一种类型,例子应该是合法的。但是,它已被Clang 和 GCC拒绝。
我想知道,这个例子中的关键字typename和template不必要的都是由未来的实现编译的吗?
这是我的代码和错误,下面我将展示一些有效的代码。
\n#include <iostream>\n#include <string>\n\n#include <nlohmann/json.hpp>\n\nusing JSON = nlohmann::json;\nusing std::cout;\nusing std::endl;\nusing std::string;\n\ntemplate <class ObjectType>\nvoid dump(const JSON &json) {\n for (auto &[key, value]: json.items()) {\n string foo = value.get<std::string>();\n cout << "Key: " << key;\n cout << " Value: " << foo << endl;\n }\n}\n\nint main(int, char **) {\n JSON json;\n json["alpha"] = "beta";\n dump<string>(json);\n} \nRun Code Online (Sandbox Code Playgroud)\n-$ g++ -std=c++17 Foo.cpp -o Foo && Foo\nFoo.cpp: In function \xe2\x80\x98void dump(const JSON&)\xe2\x80\x99:\nFoo.cpp:14:37: error: expected primary-expression before \xe2\x80\x98>\xe2\x80\x99 token\n 14 | string foo = …Run Code Online (Sandbox Code Playgroud) 考虑到以下代码示例,我希望必须template在此处使用关键字来指导编译器将变量视为v模板。然而,MSVC 拒绝使用该template关键字,而 Clang 和 GCC 实际上需要它。在这种情况下,C++20 标准中的哪条具体规则强制或禁止使用关键字template?
struct s {
template<typename...>
static constexpr auto v = true;
};
// all ok
static_assert([](auto x){ return decltype(x)::template v<>; }(s{}));
// clang ok, gcc ok, msvc nope
static_assert([](auto x){ return x.template v<>; }(s{}));
// clang nope, gcc nope, msvc ok
static_assert([](auto x){ return x.v<>; }(s{}));
Run Code Online (Sandbox Code Playgroud)
来自 Clang 的错误消息:
<source>:10:36: error: use 'template' keyword to treat 'v'
as a dependent template name
10 | static_assert([](auto …Run Code Online (Sandbox Code Playgroud) 我仍然在试图从迁移到MSVC GCC,但我似乎无法找到解决如下问题:
template < typename A, typename B, typename C, typename D >
class Test
{
public:
Test (B* pObj, C fn, const D& args) : _pObj(pObj), _fn(fn), _args(args)
{
}
A operator() ()
{
return _args.operator() < A, B, C > (_pObj, _fn); // error: expected primary-expression before ',' token
}
B* _pObj;
C _fn;
D _args;
};
Run Code Online (Sandbox Code Playgroud)
请帮忙!
我正在两个编译器(Clang on Xcode v5.0.2和Visual Studio 2012 Update 4)中编写一个跨平台的应用程序,我遇到了两个编译器不同意template关键字使用所需语法的场景.嵌套声明.
这是代码(归结为一个易于重现的测试用例):
template<typename T>
struct Base
{
template<typename U>
struct InnerBase
{};
};
template<typename T, typename U>
struct Derived : public Base<T>
{
// the "template" keyword is REQUIRED in Clang/OSX
struct InnerDerived : public Base<T>::template InnerBase<U>
{};
// the "template" keyword is FORBIDDEN in Visual Studio 2012
struct InnerDerived : public Base<T>::InnerBase<U>
{};
};
int main()
{
Derived<int, int>::InnerDerived foo;
}
Run Code Online (Sandbox Code Playgroud)
如上所述,两个编译器不同意使用"template"关键字.
对于Clang,如果不包含template关键字,则错误为:
使用'template'关键字将'InnerBase'视为依赖模板名称
对于Visual Studio,当 …