任何人都可以提供比较或具体细节,说明在GCC和MS编译器中如何在编译和/或链接时处理模板实例化?这个过程在静态库,共享库和可执行文件的上下文中是不同的吗?我找到了关于GCC如何处理它的文档,但我不确定这些信息是否仍然指的是当前的状态.在编译我的库时,我应该使用他们建议的标志,例如-fno-implicit-templates吗?
我所知道的(可能不一定正确)是:
在SO上阅读问题,评论和答案,我一直听说MSVC没有正确地实现两阶段模板查找/实例化.
据我所知,到目前为止,MSVC++只对模板类和函数进行了基本的语法检查,并没有检查模板中使用的名称是否至少被声明了或者沿着这些行.
它是否正确?我错过了什么?
为什么C++标准为模板定义了两个阶段查找?非依赖声明和定义的查找是否也可以推迟到实例化阶段?
我正在阅读这个Stack Overflow问题,我在该问题的代码中添加了一个构造函数,如下所示,
class Foo {
struct Bar {
int i;
Bar(int a = 5) :i(a) {};
};
public:
Bar Baz() { return Bar(); }
};
int main() {
Foo f;
// Foo::Bar b = f.Baz(); // error
auto b = f.Baz(); // ok
std::cout <<"b.i="<< b.i<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
代码输出b.i=5.在那个问题中,它得出结论,私有的名称是不可访问的,但类型是.那么一般来说,类型和名称之间的区别是什么?
并说我有两个特定的场景.
以下两个声明之间的区别是什么?为什么我能得到的输出b.i=5从auto b = f.Baz();?
Foo::Bar b = f.Baz();
auto b = f.Baz();
Run Code Online (Sandbox Code Playgroud)如果我typedef Bar B;在公共部分添加,Foo以下有什么区别?
Foo::Bar b …Run Code Online (Sandbox Code Playgroud)以下代码编译并给出结果(GCC和clang):
template <typename T> struct Derived;
struct Base
{
template <typename T>
void foo(T * const t)
{
dynamic_cast<Derived<T> * const>(this)->bar(t);
}
};
template <typename T>
struct Derived : Base
{
void bar(T const *) const { }
};
Run Code Online (Sandbox Code Playgroud)
代码调用fooin Base到barin Derived.
作为参考,以下代码无法编译:
struct Derived2;
struct Base2
{
template <typename T>
void foo(T * const t)
{
dynamic_cast<Derived2 * const>(this)->bar(t);
}
};
struct Derived2 : Base2
{
template <typename T>
void bar(T const *) …Run Code Online (Sandbox Code Playgroud) 我有这个代码:
struct Base {};
template<typename T>
struct Foo : Base {};
struct Bar {
template<typename T> // v--- What's happening here?
Bar(T foo) : baz{std::make_unique<Foo>(foo)} {}
std::unique_ptr<Base> baz;
};
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,GCC和Clang接受并编译了它.它似乎推断出模板参数Foo,但它没有意义.为什么编译器接受即使没有重载std::make_unique需要模板模板参数呢?Live example
From the cppreference.com article on std::enable_if,
Notes
A common mistake is to declare two function templates that differ only in their default template arguments. This is illegal because default template arguments are not part of function template's signature, and declaring two different function templates with the same signature is illegal.
/*** WRONG ***/
struct T {
enum { int_t,float_t } m_type;
template <
typename Integer,
typename = std::enable_if_t<std::is_integral<Integer>::value>
>
T(Integer) : m_type(int_t) {}
template <
typename Floating,
typename = …Run Code Online (Sandbox Code Playgroud) c++ templates sfinae language-lawyer template-meta-programming
啊
template <typename T>
class A
{
public:
int a;
}
Run Code Online (Sandbox Code Playgroud)
BH
template <typename T>
class B : public A<T>
{
public:
int f();
}
template <typename T>
int B<T>::f()
{
int t;
t = this->a; //Okay
t = a //Error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么我不使用时会发生错误this->?
我可以省略this->使用某种方法吗?
(我修正了一些错误)
以下C++代码无法编译,例如使用g ++ - 4.7或clang ++ - 3.2:
struct Bar {};
template<typename T>
void foo(T t, Bar bar) {
t.compiler_does_not_care();
bar.nonexistent_method();
}
int main() {}
Run Code Online (Sandbox Code Playgroud)
为什么编译器检查模板函数foo的代码是否具有语义正确性(他们可以在哪里),即使它从未实例化过?这个标准是否合规?
以及如何修复代码?
这是代码: https: //godbolt.org/z/vcP6WKvG5
#include <memory>
#include <utility>
enum class Format {
Number,
Text,
};
template <template <Format> typename Visitor, typename... Args>
void switchByFormat(Format format, Args&&... args) {
switch(format) {
case Format::Number:
Visitor<Format::Number>::visit(std::forward<Args>(args)...);
break;
case Format::Text:
Visitor<Format::Text>::visit(std::forward<Args>(args)...);
break;
}
}
struct AstNode {};
template <Format format>
struct ANode: public AstNode {};
using AstNodePtr = std::shared_ptr<AstNode>;
template <template <Format> typename AstNodeT,
typename... Args>
struct AstNodeFactory {
template <Format format>
struct Visitor {
static void visit(AstNodePtr& result, Args&&... args)
{
result = …Run Code Online (Sandbox Code Playgroud) c++ ×10
templates ×9
c++11 ×1
c++14 ×1
gcc ×1
inheritance ×1
name-lookup ×1
sfinae ×1
types ×1
visual-c++ ×1